在同一列中选择一个列值和最近/最近的值

时间:2019-01-27 12:55:16

标签: sql teradata

我有两列

Key,Val
1    31
2    43
3    41
4    100

我的预期输出是

Key,Val,closestVal
1    31    41
2    43    41
3    41    43
4    100   43

什么是最简单的SQL查询才能获得预期的输出?

2 个答案:

答案 0 :(得分:1)

我们可以在此处将ABSROW_NUMBER一起使用:

WITH cte AS (
    SELECT t1.Key, t1.Val, t2.Val AS closestVal,
        ROW_NUMBER() OVER (PARTITION BY t1.Key ORDER BY ABS(t1.Val - t2.Val)) rn
    FROM yourTable t1
    INNER JOIN yourTable t2
        ON t1.Key <> t2.Key
)

SELECT Key, Val, closestVal
FROM cte
WHERE rn = 1;

enter image description here

Demo

注意:上面的演示适用于SQL Server,不适用于Teradata。如果KEY是Teradata中的保留关键字,那么如果打算将其用作列名,则必须对其进行转义。

答案 1 :(得分:1)

我认为性能最高的查询将使用lag()lead() -由于某些原因,Teradata不直接支持。但是:

select t.*,
       (case when abs(val - min(val) over (order by val rows between 1 preceding and 1 preceding)) <
                  abs(val - min(val) over (order by val rows between 1 following and 1 following)
            then min(val) over (order by val rows between 1 preceding and 1 preceding))
            else min(val) over (order by val rows between 1 following and 1 following)
        end) as closest_val
from t;

换句话说,不需要子查询或联接,只需要窗口函数即可。