2017-03-25 21 views
1

私のアプリでは、特定のクラスに割り当てられた車両を持っています。以下のクエリでは、特定の領域にある少なくとも1台の車両を持つすべてのクラスを選択しようとしています。MySQL Select Inner Join(ユニークのみ)

以下のコードが正常に動作し、複数の車両が位置パラメータを適合クラスの内側に存在する場合、しかし、クラスの複数のインスタンスが結果に返されます。

は、どのように私は関係なく、どのように多くの車両クラスの内部の、したがって、すべてのクラスのインスタンスが1つだけ返され、このクエリを構造化のparamaterに合うことができますか?

$get_veh = $pdo->prepare("SELECT * FROM tbl_car_class_category JOIN tbl_vehicles ON tbl_vehicles.veh_class_id = tbl_car_class_category.id_class_cat WHERE tbl_vehicles.veh_advanceLng between (:loc_long-:radius/cos(radians(:loc_lat))*69) and (:loc_long+:radius/cos(radians(:loc_lat))*69) and veh_advanceLat between (:loc_lat-(:radius/69)) and (:loc_lat+(:radius/69)) AND veh_status=:veh_status"); 

$get_veh->bindparam(":veh_status", $veh_status); 
$get_veh->bindparam(":loc_lat", $loc_lat); 
$get_veh->bindparam(":loc_long", $loc_long); 
$get_veh->bindparam(":radius", $radius); 

$get_veh->execute(); 
+0

、あなたはその後、車の数を取る – Rams

+1

間に合わせと-ソリューションは、カテゴリ別に 'グループを追加することで、クラスにして、グループを行うことができます'。しかし、これは他のデータベースでは利用できないMySQL(mis)機能を使用します。実際には、カテゴリごとに不確定な行が返されます(MySQLの将来のバージョンでは機能しない可能性があります)。 –

答えて

2

目的は、カテゴリテーブルから行だけを返している場合、我々は例えばEXISTS (correlated subquery)

JOINを置き換えることができます:

SELECT c.* 
    FROM tbl_car_class_category c 
    WHERE EXISTS 
     (SELECT 1 
      FROM tbl_vehicles v 
     WHERE v.veh_class_id = c.id_class_cat 
      AND v.veh_advanceLng 
       BETWEEN (:loc_long-:radius/cos(radians(:loc_lat))*69) 
        AND (:loc_long+:radius/cos(radians(:loc_lat))*69) 
      AND v.veh_advanceLat 
       BETWEEN (:loc_lat-(:radius/69)) 
        AND (:loc_lat+(:radius/69)) 
      AND v.veh_status=:veh_status 
    ) 

我々はまた、車両からの行を返すために必要がある場合テーブルでは、インラインビューでの集約とJOINを使用できます。

SELECT c.* 
     , g.* 
    FROM tbl_car_class_category c 
    JOIN (SELECT v.veh_class_id 
       , MIN(v.id) AS min_id -- PK or unique identifier  
      FROM tbl_vehicles v 
      AND v.veh_advanceLng 
       BETWEEN (:loc_long-:radius/cos(radians(:loc_lat))*69) 
        AND (:loc_long+:radius/cos(radians(:loc_lat))*69) 
      AND v.veh_advanceLat 
       BETWEEN (:loc_lat-(:radius/69)) 
        AND (:loc_lat+(:radius/69)) 
      AND v.veh_status=:veh_status 
      GROUP BY v.veh_class_id 
     ) m 
    ON m.veh_class_id = c.id_class_cat 
    JOIN tbl_vehicles g 
    ON g.id   = m.min_id 
    AND g.veh_class_id = m.veh_class_id 
    ORDER BY ... 

は(注:これはid_class_cattbl_car_class_categoryで一意であることを前提として)

+0

ブーム。完璧なソリューション、ありがとう! (注:私は車のテーブルから何も行を必要としなかったので、この答えの上のコードスニペットがうまくいった) –

0

LIMITを試しましたか?

$get_veh = $pdo->prepare("SELECT * FROM tbl_car_class_category JOIN tbl_vehicles ON tbl_vehicles.veh_class_id = tbl_car_class_category.id_class_cat WHERE tbl_vehicles.veh_advanceLng between (:loc_long-:radius/cos(radians(:loc_lat))*69) and (:loc_long+:radius/cos(radians(:loc_lat))*69) and veh_advanceLat between (:loc_lat-(:radius/69)) and (:loc_lat+(:radius/69)) AND veh_status=:veh_status LIMIT 1"); 

http://www.mysqltutorial.org/mysql-limit.aspx

またはDISTINCT:あなたは(偽の例:分)を使用することができ、クラスごとに単一の行取得のためのhttps://dev.mysql.com/doc/refman/5.7/en/distinct-optimization.html

0

によって集約functioとグループを(行います*の代わりにcol1、col2、col3があると仮定してテーブルスキーマが存在しない場合

$get_veh = $pdo->prepare("SELECT 
       tbl_car_class_category.id_class_cat 
        , min(col1) 
        , min(col2) 
        , min(col3) 
    FROM tbl_car_class_category 
    JOIN tbl_vehicles ON tbl_vehicles.veh_class_id = tbl_car_class_category.id_class_cat 
    WHERE tbl_vehicles.veh_advanceLng between (:loc_long-:radius/cos(radians(:loc_lat))*69) 
        and (:loc_long+:radius/cos(radians(:loc_lat))*69) 
        and veh_advanceLat between (:loc_lat-(:radius/69)) 
        and (:loc_lat+(:radius/69)) AND veh_status=:veh_status 
        GROUP BY tbl_car_class_category.id_class_cat");