选择两个值,以及前两个值之间具有最小距离的两个值

时间:2019-01-27 15:03:11

标签: sql teradata

我有三列

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

2 个答案:

答案 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),xy,以提高可读性。
  • 根据您的建议,它使用欧几里得公式来计算距离:abs(x2-x1) + abs(y2-y1)
  • 请注意,如果几条记录是最小的等距,则将返回多行。

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        |