首次发布,我会尽力遵守最佳做法。
我正在尝试构建一个测量用户位置的MySQL查询(在查询中分别表示为$Lat
和$Lng
表示纬度和经度)。查询应该返回最接近用户的50个站点。
问题是我的表格中的数据包含每个站点入口的位置,我只需要每个站点最近的站点入口!
这是我的问题:
SELECT id, lat, lng, station_name, routes,
( 3959 * acos( cos( radians($Lat) )
* cos( radians( lat ) ) * cos( radians( lng ) -
radians($Lng) ) + sin( radians($Lat) ) * sin( radians( lat ) ) ) ) AS distance
FROM subway_stations ORDER BY distance LIMIT 0 , 50;
以上MySQL查询完成以下操作:
我需要将这些结果组合在一起,以便每个站点只返回一个记录,距离列中值最小的记录,即最靠近用户的站点入口。
我尝试过使用GROUP BY
,但我似乎错误地实现了它,因为返回的结果不是理想的结果。
答案 0 :(得分:0)
如果每个电台只需要一个最小的记录,则不需要LIMIT .. 只是做
$result = mysql_query("SELECT id, lat, lng, station_name, routes, MIN(
( 3959 * acos( cos( radians($Lat) ) * cos( radians( lat ) ) *
cos( radians( lng ) - radians($Lng) ) + sin( radians($Lat) ) *
sin( radians( lat ) ) ) ) AS distance )
FROM subway_stations
GROUP BY station_name;
每个站点只返回一条距离最小的记录。
答案 1 :(得分:0)
如果不设置示例数据库,很难知道,但我怀疑您要进行以下更改:
在查询末尾添加group by station_name, id, lat, lng
不属于select
子句的所有group by
字段都需要聚合函数。最明显的是,distance
应该需要min(...)
我不确定是否可以使用order
和limit
子句。如果您遇到问题,请暂时(暂时)将它们拿出来并开始工作。为方便起见,请将此查询称为Q1。
如果无法使用order by
和limit
子句(实验并查看),则需要嵌套查询。这看起来像select * from (...Q1...) t1 ORDER BY distance LIMIT 0,50
。 t1
为内部选择分配了一个临时名称,但未在此查询中实际使用,但语法需要。
作为优化,您可能希望在内部having
查询中添加Q1
子句。也就是说,如果您知道边界距离,请添加HAVING distance<XXXXX
。
请注意,可能不需要步骤3 - 5,我不确定第3步。
答案 2 :(得分:0)
您可以更轻松地使用php获取每个站点最近的入口。
这实际上是一个常见问题,您需要使用子查询来解决。
我假设id
只是一个行ID,并不是每个站唯一的。
SELECT subway_stations.* FROM (
SELECT station_name, MIN(
( 3959 * acos( cos( radians($Lat) ) * cos( radians( lat ) ) *
cos( radians( lng ) - radians($Lng) ) + sin( radians($Lat) ) *
sin( radians( lat ) ) ) )
) AS distance
FROM subway_stations
GROUP BY station_name
) AS min_distances
JOIN subway_stations ON (
min_distances.station_name = subway_stations.station_name
AND ( 3959 * acos( cos( radians($Lat) ) * cos( radians( lat ) ) *
cos( radians( lng ) - radians($Lng) ) + sin( radians($Lat) ) *
sin( radians( lat ) ) )
) = min_distances.distance
)
这是解决您问题的典型“纯mysql”解决方案。但是,由于获取距离所涉及的计算程度,您可能希望: - 使用您的初始查询,并使用php OR获取每个站的最短距离 - 运行上面的内部查询,但将其结果插入临时表,然后执行上述查询的等效操作,除非计算的距离替换为临时表的计算距离。