簡體   English   中英

MySQL選擇內部聯接(僅唯一)

[英]MySQL Select Inner Join (Only Unique)

在我的應用中,我有分配給特定類別的車輛。 在下面的查詢中,我試圖選擇其中某個區域內至少有一輛車輛的所有類別。

下面的代碼運行良好,但是,如果類中有多個適合位置參數的車輛,則結果中將返回該類的多個實例。

如何構造該查詢,以便無論類中有多少適合該參數的車輛返回每個類的一個實例?

$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();

如果意圖是僅返回類別表中的行,則可以用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
      )

如果還需要從vehicle表返回一行,則可以在內聯視圖中使用聚合,並在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是唯一的)

您嘗試過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

為了獲得每個類的單行,您可以使用(假的:min)聚合函數並分組

(在沒有表模式的情況下,假設您使用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");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM