问题
I have three columns
Key, x1, y1
1 31 34
2 43 40
3 41 44
4 100 40
My expected output is:
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
what can be the simplest sql query to have the expected output? Note that both the values x1,y1 are considered while finding out the closest pair
回答1:
A possible solution for your use case would to self-join the table using a NOT EXIST
clause to ensure that the record being joined is the closest possible record to the current record.
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;
Notes :
- I renamed the table fields to
k
(ey),x
andy
for more readbility. - As suggested by you, this uses Euclidian formula to compute the distance :
abs(x2-x1) + abs(y2-y1)
- Please note that, if several records are smallest and equidistant, multiple rows will be returned.
View on DB Fiddle :
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 |
回答2:
I think that in line 4 of your expected result the closest values are wrong.
It should be:
4 100 40 43 40
at least this is the result I get by this:
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
Results:
| 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 |
来源:https://stackoverflow.com/questions/54389523/select-two-values-and-the-two-values-with-which-former-values-have-minimum-dista