【问题标题】:Group By with min distance in mysql在mysql中按最小距离分组
【发布时间】:2015-02-28 09:30:42
【问题描述】:

我被这个mysql查询卡住了

SELECT hotels.radius,
hotels.hotel_id,
hotel_names.name_id,
hotel_names.image,
hotel_names.name,
hotel_names.description, 
hotels.hotel_address,hotels.lat,hotels.lng, 
( 6371 * acos( cos( radians( 45.4046728 ) ) * cos( radians( lat ) ) * 
cos( radians( lng ) - radians( 11.8485039 ) ) + 
sin( radians( 45.4046728 ) ) * sin( radians( lat ) ) ) ) AS distance 
FROM hotels 
INNER JOIN hotel_names 
ON hotels.name_id = hotel_names.name_id 
ORDER BY `distance` ASC

这个查询的结果

预期的结果应该是与 name_id 的 GROUP BY 并标记为黄色

检查此http://gyazo.com/18b705b042e289d5d0a2dc9adde4c715,预期结果应为酒店 ID 17、23、26、28、25 谢谢

【问题讨论】:

  • 编辑您的问题并将答案和预期答案发布为文本而不是图片。
  • @Rahul 检查此gyazo.com/18b705b042e289d5d0a2dc9adde4c715,预期结果应为酒店 ID 17、23、26、28、25
  • @SamArulRaj 嗯,那仍然是一张照片。提供适当的 DDL 和/或 sqlfiddle
  • @Strawberry 我请大家找到答案!这里讨论的不是图片或文字
  • 这是一个很好的问题!这是一个讨论可能解决方案的策略的博客:xaprb.com/blog/2006/12/07/…

标签: mysql google-maps-api-3 distance


【解决方案1】:

这是您的查询,诚然是冗长的:

SELECT y.radius,y.hotel_id,y.name_id,y.image,y.name,y.description, y.hotel_address,y.lat,hotels.lng,y.distance
FROM (
    SELECT hotels.name_id, min( 6371 * acos( cos( radians( 45.4046728 ) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians( 11.8485039 ) ) + sin( radians( 45.4046728 ) ) * sin( radians( lat ) ) ) ) AS mindistance FROM hotels INNER JOIN hotel_names ON hotels.name_id = hotel_names.name_id GROUP BY hotels.name_id
) AS x
INNER JOIN (
    SELECT hotels.radius,hotels.hotel_id,hotel_names.name_id,hotel_names.image,hotel_names.name,hotel_names.description, hotels.hotel_address,hotels.lat,hotels.lng, ( 6371 * acos( cos( radians( 45.4046728 ) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians( 11.8485039 ) ) + sin( radians( 45.4046728 ) ) * sin( radians( lat ) ) ) ) AS distance
    FROM hotels INNER JOIN hotel_names
    ON hotels.name_id = hotel_names.name_id
) AS y
ON y.name_id = x.name_id AND y.distance = x.mindistance;

我使用了self-join 策略,它首先获得一个表,其中只包含酒店name_id 组和一个我命名为mindistance 的变量,它是每个组到您的硬编码位置的最小距离.此中间表在上述查询中称为 x,如果您将其作为单独的查询运行,它看起来像这样:

--------------------------------
| name_id |    mindistance     |
--------------------------------
|    1    | 4.932831427954488  |
|    2    | 2.7469817798115566 |
|    4    | 6.677055216749393  |
|    5    | 4.359018738728522  |
|    6    | 4.6047991286091055 |
--------------------------------

然后我将此表加入到您在上述问题中的原始INNER JOIN 查询结果的表中。请注意,此INNER JOINON 条件仅匹配每个name_id 的一条记录,该记录也具有该组中的最小距离。我没有对我的结果进行排序,但我欢迎您尝试此查询并让我们知道它是否适合您。

经过进一步思考,这个查询可以通过一些事情来简化。如果您的初始结果只有一个表格,那会有所帮助。此外,如果您创建了一个包含距离的专用列,这也会使事情更容易阅读。

【讨论】:

    猜你喜欢
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多