SQL:如何找到从一列到下一列最接近匹配的索引日期?

问题描述

我有以下示例 MyTable,它已从原始数据集分组。

我想找到“plus_one”值与给定“dept”中的“value”列最接近匹配(上面的第一个结果)的日期。这需要在“return_dt”列中生成

例如,在第一行,“衣服”部门的“plus_one”列中的1.2最接近“值”列中的1.36667,因此第一行需要返回对应的日期(6/19/ 20) 在同一部门的“return_dt”列中。

我熟悉窗口函数并使用 ORDER BY abs() 找到最接近的匹配项。我无法将它们放在一起以在单个表中查找索引日期。

end_dt 部门 价值 plus_one return_dt
6/30/2020 0:00 衣服 0.2 1.2 6/19/2020
6/29/2020 0:00 衣服 0.393333 1.393333 6/18/2020
6/28/2020 0:00 衣服 0.393333 1.393333 6/18/2020
6/27/2020 0:00 衣服 0.393333 1.393333 6/17/2020
6/26/2020 0:00 衣服 0.573333 1.573333 6/17/2020
6/25/2020 0:00 衣服 0.726667 1.726667 6/16/2020
6/24/2020 0:00 衣服 0.853333 1.853333 6/15/2020
6/23/2020 0:00 衣服 1.02 2.02 6/12/2020
6/22/2020 0:00 衣服 1.166667 2.166667 6/12/2020
6/21/2020 0:00 衣服 1.166667 2.166667
6/20/2020 0:00 衣服 1.166667 2.166667
6/19/2020 0:00 衣服 1.366667 2.366667
6/18/2020 0:00 衣服 1.5 2.5
6/17/2020 0:00 衣服 1.713333 2.713333
6/16/2020 0:00 衣服 1.84 2.84
6/15/2020 0:00 衣服 1.986667 2.986667
6/14/2020 0:00 衣服 1.986667 2.986667
6/13/2020 0:00 衣服 1.986667 2.986667
6/12/2020 0:00 衣服 2.24 3.24
6/30/2020 0:00 玩具 0.2 1.2 6/19/2020
6/29/2020 0:00 玩具 0.393333 1.393333 6/18/2020
6/28/2020 0:00 玩具 0.393333 1.393333 6/18/2020
6/27/2020 0:00 玩具 0.393333 1.393333 6/17/2020
6/26/2020 0:00 玩具 0.573333 1.573333 6/17/2020
6/25/2020 0:00 玩具 0.726667 1.726667 6/16/2020
6/24/2020 0:00 玩具 0.853333 1.853333 6/15/2020
6/23/2020 0:00 玩具 1.02 2.02 6/12/2020
6/22/2020 0:00 玩具 1.166667 2.166667 6/12/2020
6/21/2020 0:00 玩具 1.166667 2.166667
6/20/2020 0:00 玩具 1.166667 2.166667
6/19/2020 0:00 玩具 1.366667 2.366667
6/18/2020 0:00 玩具 1.5 2.5
6/17/2020 0:00 玩具 1.713333 2.713333
6/16/2020 0:00 玩具 1.84 2.84
6/15/2020 0:00 玩具 1.986667 2.986667
6/14/2020 0:00 玩具 1.986667 2.986667
6/13/2020 0:00 玩具 1.986667 2.986667
6/12/2020 0:00 玩具 2.24 3.24
6/30/2020 0:00 游戏 0.2 1.2 6/19/2020
6/29/2020 0:00 游戏 0.393333 1.393333 6/18/2020
6/28/2020 0:00 游戏 0.393333 1.393333 6/18/2020
6/27/2020 0:00 游戏 0.393333 1.393333 6/17/2020
6/26/2020 0:00 游戏 0.573333 1.573333 6/17/2020
6/25/2020 0:00 游戏 0.726667 1.726667 6/16/2020
6/24/2020 0:00 游戏 0.853333 1.853333 6/15/2020
6/23/2020 0:00 游戏 1.02 2.02 6/12/2020
6/22/2020 0:00 游戏 1.166667 2.166667 6/12/2020
6/21/2020 0:00 游戏 1.166667 2.166667
6/20/2020 0:00 游戏 1.166667 2.166667
6/19/2020 0:00 游戏 1.366667 2.366667
6/18/2020 0:00 游戏 1.5 2.5
6/17/2020 0:00 游戏 1.713333 2.713333
6/16/2020 0:00 游戏 1.84 2.84
6/15/2020 0:00 游戏 1.986667 2.986667
6/14/2020 0:00 游戏 1.986667 2.986667
6/13/2020 0:00 游戏 1.986667 2.986667
6/12/2020 0:00 游戏 2.24 3.24

我已经尝试过类似的相关查询

select t.*,(select t2.end_dt
       from t t2
       where t2.value > t.plus_one
       order by t2.value
       limit 1
      ) as return_dt
from t;

但 Netezza 说“错误 [HY000] 错误:(2) 不支持这种形式的相关查询 - 考虑重写”

有什么想法可以为 return_dt 创建列吗?

解决方法

横向连接或相关子查询似乎是最简单的方法:

select t.*,(select t2.end_dt
        from t t2
        where t2.dept = t.dept and
              t2.value > t.plus_one
        order by t2.value
        limit 1
       ) as return_dt
from t;

在没有相关子查询的情况下,这是相当痛苦的(而且效率低下)。但 。 . .

select t.*
from (select t.end_dt,t.dept,t.value,t.plus_one,tnext.end_dt as return_dt,row_number() over (partition by t.end_dt,t.plus_one order by tnext.value asc) as seqnum
      from t left join
           t tnext
           on tnext.dept = t.dept and
              tnext.value > t.plus_one
     ) t
where seqnum = 1;