我有下表
位置:
userId | zip |
----------------
1 | 12383 |
1 | 10253 |
2 | 10523 |
2 | 14856 |
2 | 10251 |
3 | NULL |
对于给定的整数X,我想根据谁具有最接近X的列zip
中的整数以及相应的zip
数来对用户进行排序。如果用户在字段NULL
中具有值zip
,那么他应该在结尾显示。
实施例: 对于X = 5000,我想得到输出
userId | zip |
----------------
2 | 10251 |
1 | 10253 |
3 | NULL |
我设法将userId正确排序为:
SELECT userId, MIN(ABS(3-zip)) as dist FROM location GROUP BY userId Order by -dist DESC
制作表格
userId | dist |
-----------------
2 | 5251 |
1 | 5253 |
3 | NULL |
但我怎样才能获得最近的邮政编码?
答案 0 :(得分:1)
试试这个:
SELECT userId, ABS(MIN(ABS(zip-3)) + IF(zip - 3 >= 0, 3, -3)) as dist
FROM location
GROUP BY userId
Order by ABS(MIN(ABS(zip-3)) + IF(zip - 3 >= 0, 3, -3)) IS NOT NULL DESC, userId DESC
<强> 编辑: 强>
SELECT userId, SUBSTRING_INDEX(GROUP_CONCAT(zip ORDER BY ABS(zip - 3)), ',', 1) as dist
FROM location
GROUP BY userId
Order by SUBSTRING_INDEX(GROUP_CONCAT(zip ORDER BY ABS(zip - 3)), ',', 1) IS NOT NULL DESC, userId DESC
答案 1 :(得分:1)
SELECT t1.userId,
t1.zip
FROM location t1
INNER JOIN
(
SELECT userId, MIN(ABS(3-zip)) AS dist
FROM location
GROUP BY userId
) t2
ON t1.userId = t2.userId AND
(ABS(3 - t1.zip) = t2.dist OR t2.dist IS NULL) -- pay careful attention here
ORDER BY -t2.dist DESC -- join on the absolute difference
在这里演示:
此查询中有一些技巧:
ABS(# - zip)
可确保我们选择最接近的拉链,无论其是高还是低t2.dist IS NULL
条件包括拥有NULL
邮政编码的用户ORDER BY -t2.dist DESC
按升序顺序对邮政编码进行排序,同时将NULL
放在结果集的结尾。