如何解决SQL Lag distinct - 与前一个不同的值
我通过多列表简化了以下内容。
Person Period Cost_Center Previous_Cost_Center
----------- ---------------- ----------- ----------------------
123 2019003 1
123 2019004 1
123 2019005 2
123 2019006 2
123 2019007 3
对于每个人,我想找到他以前的成本中心并将其保存在相应的列中。以前的成本中心必须与当前的不同。
我想得到什么:
Person Period Cost_Center Previous_Cost_Center
----------- ---------------- ----------- ---------------------
123 2019003 1 NULL
123 2019004 1 NULL
123 2019005 2 1
123 2019006 2 1 <----- Problematic row
123 2019007 3 2
在此期间的标准 LAG() 函数实际上会输出:
Person Period Cost_Center Previous_Cost_Center
----------- ---------------- ----------- ---------------------
123 2019003 1 NULL
123 2019004 1 NULL
123 2019005 2 1
123 2019006 2 2 <----- Problematic row
123 2019007 3 2
在有问题的行中,我想要的是最后一个不同的 Cost_Center 值,即 1 而不是 2。 我想到使用的是检查之前的Cost_Center是否不同:
CASE
WHEN
LAG ( Cost_Center ) OVER ( PARTITION BY Person ORDER BY Period ) != Cost_Center
THEN
LAG ( Cost_Center ) OVER ( PARTITION BY Person ORDER BY Period )
ELSE
Previous_Cost_Center
END
AS Previous_Cost_Center,
但是我最终在第 4 行中完全没有 Previous_Cost_Center 值。 如何使用 SQL 将其存档?如何接管最后一个不同的 Cost_Center 值以将其保存在按期间排序的 Previous_Cost_Center 中?
解决方法
将#test 替换为您的表名。它只是选择,您可以更改它以进行更新。请对此进行测试,因为您将遇到不同的情况。
SELECT s.person,s.period,s.cost_center,CASE WHEN z.person IS NULL THEN NULL ELSE z.cc END AS Previous_Cost_Center
FROM #test s
LEFT JOIN (SELECT *
FROM (SELECT t1.*,t2.cost_center cc,Row_number()OVER (partition BY t2.person,t1.period ORDER BY t2.period DESC) RN
FROM #test t1
JOIN #test t2
ON t1.person = t2.person
AND t1.period > t2.period
WHERE t1.cost_center <> t2.cost_center)s
WHERE rn = 1
)z
ON s.person = z.person
AND s.period = z.period
,
您可以使用窗口函数执行此操作,但由于 ignore null
s 选项不可用,因此比需要的更棘手。
首先,您要为同一组的相邻值分配一个分组。
其次,您希望在分组前一个成本中心时给出第一个值。
第三,您希望在整个团队中“传播”该价值。
select t.*,max(case when immediate_prev_cost_center <> cost_center then immediate_prev_cost_center
end) over (partition by person,cost_center,(seqnum - seqnum_2)
) as prev_cost_center
from (select t.*,row_number() over (partition by person order by period) as seqnum,row_number() over (partition by person,cost_center order by period) as seqnum_2,lag(cost_center) over (partition by person order by period) as immediate_prev_cost_center
from t
) t;
行号的差异定义了组。 max()
在整个组中传播先前的值。
Here 是一个 dbfiddle。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。