我有三列
Key, x1, y1
1 31 34
2 43 40
3 41 44
4 100 40
我的预期输出是:
Key, x1, y2, closest_x1, closest_y2
1 31 34 43 40
2 43 40 41 44
3 41 44 43 40
4 100 40 41 44
什么是最简单的sql查询才能获得预期的输出? 请注意,在找出最接近的对时会同时考虑值x1,y1
答案 0 :(得分:2)
我认为在预期结果的第4行中,最接近的值是错误的。
应该是:
4 100 40 43 40
至少这是我从中得到的结果:
select t.*, tt.x1 closest_x1, tt.y1 closest_y1
from tablename t
inner join tablename tt
on tt.key = (
select min(key) from tablename where power(x1 - t.x1, 2) + power(y1 - t.y1, 2) = (
select min(power(x1 - t.x1, 2) + power(y1 - t.y1, 2)) from tablename where key <> t.key
)
)
order by t.key
结果:
| key | x1 | y1 | closest_x1 | closest_y1 |
| ---- | --- | --- | ---------- | ---------- |
| 1 | 31 | 34 | 43 | 40 |
| 2 | 43 | 40 | 41 | 44 |
| 3 | 41 | 44 | 43 | 40 |
| 4 | 100 | 40 | 43 | 40 |
答案 1 :(得分:2)
针对您的用例的一种可能的解决方案是使用NOT EXIST
子句自联接表,以确保要联接的记录是与当前记录最接近的记录。
SELECT t1.*, t2.x closest_x, t2.y closest_y
FROM mytable t1
INNER JOIN mytable t2
ON t2.k <> t1.k
AND NOT EXISTS (
SELECT 1
FROM mytable t3
WHERE
t3.k <> t1.k
AND abs(t1.x - t3.x) + abs(t1.y - t3.y) < abs(t1.x - t2.x) + abs(t1.y - t2.y)
)
ORDER BY 1;
注意:
k
(ey),x
和y
,以提高可读性。abs(x2-x1) + abs(y2-y1)
SELECT t1.*, t2.x closest_x, t2.y closest_y
FROM mytable t1
INNER JOIN mytable t2
ON t2.k <> t1.k
AND NOT EXISTS (
SELECT 1
FROM mytable t3
WHERE
t3.k <> t1.k
AND abs(t1.x - t3.x) + abs(t1.y - t3.y) < abs(t1.x - t2.x) + abs(t1.y - t2.y)
)
ORDER BY 1;
| k | x | y | closest_x | closest_y | | --- | --- | --- | --------- | --------- | | 1 | 31 | 34 | 43 | 40 | | 2 | 43 | 40 | 41 | 44 | | 3 | 41 | 44 | 43 | 40 | | 4 | 100 | 40 | 43 | 40 |