[英]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_cat
在tbl_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.