SQL - Unqiue结果基于标准

时间:2016-06-01 20:40:54

标签: mysql sql greatest-n-per-group

制作经销商定位器,人们搜索附近的经销商。我希望它以这样的方式工作:如果经销商在该人附近有多个分支,则只有最近的分支显示。因此,“名称”字段在结果中应该是唯一的,结果显示与搜索人员的距离最小,而其他行具有相同的“名称”字段。我也想要只有最近的经销商级别或奖牌所示的5个经销商。现在我有以下内容:

$query = sprintf("SELECT
name, address, contact, image, medal, phone, email, website, lat, lng,
( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance
FROM dealers
HAVING distance < 60
ORDER BY medal, distance
LIMIT 0 , 5",
mysql_real_escape_string($center_lat),
mysql_real_escape_string($center_lng),
mysql_real_escape_string($center_lat),
mysql_real_escape_string($radius));
$result = mysql_query($query);

从我读过的内容来看,我觉得我需要这样做:

SELECT * FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY distance) AS num
FROM dealers)a
WHERE a.num = 1

或类似的东西,但我不能让它正常工作。任何有关如何使其发挥作用的见解将不胜感激。

2 个答案:

答案 0 :(得分:0)

获得每个经销商的最小距离,其中前五个。然后从表格中再次选择以获得完整记录,但只获取经销商和距离已经识别的那些记录。

WITH子句会有所帮助,但MySQL并不支持它。嗯,......

SELECT
  name, address, contact, image, medal, phone, email, website, lat, lng,
  ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance
FROM dealers
WHERE (name, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) )) IN
(
  SELECT
    name, min( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance
  FROM dealers
  GROUP BY name
  HAVING distance < 60
  ORDER BY distance
  LIMIT 5
)
ORDER BY distance, medal;

答案 1 :(得分:0)

最终解决方案是:

        SELECT name, address, contact, image, medal, phone, email, website, lat, lng, 
    ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance 
    FROM dealers 
    WHERE (name,
        ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) )
        IN 
        (SELECT name, distance 
            FROM (SELECT name,
            MIN( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance
            FROM dealers 
            WHERE (3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) < 90
            GROUP BY name) 
        t) 

    ORDER BY medal, distance 
    LIMIT 0, 5",

    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lng),
    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lng),
    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lng),
    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lat),
    mysql_real_escape_string($center_lng),
    mysql_real_escape_string($center_lat)

谢谢Thorsten Kettner,让我走上正轨!