我有一张类似于以下内容的表格:
INITIAL TABLE
-------------------------------------------------------
ID Date Author Data1 Data9
== ================ ========== ======= ... =======
1 2017-06-04 16:47 John Smith Foo Bar
2 2017-06-04 16:50 John Smith Goo Bar
3 2017-06-04 16:52 John Smith Hoo Car
4 2017-06-04 16:55 Bill Plith Foo Bar
5 2017-06-04 16:59 John Smith Foo Car
6 2017-06-04 17:04 Bill Plith Foo Bar
数据来自用户从中央源更改数据集。用户的名称,进行更改的日期时间以及所有数据字段的刷新'只要对任何数据字段进行了更改,就会将值附加到表中。
问题在于,手动检查每列以查看实际更改的位置非常繁琐。有时会对一个字段进行更改,有时会对多个字段进行更改,有时根本不会进行任何更改(如果用户单击"保存更改"实际上未进行任何更改,则新行将仍然被添加到表中。)
我想要查询表格以产生类似于以下内容的结果:
CHANGE TABLE
--------------------------------------------------------
Date Author Changes
================ ========== ========================
2017-06-04 16:50 John Smith Data1 was changed to Goo
2017-06-04 16:52 John Smith Data1 was changed to Hoo
2017-06-04 16:52 John Smith Data9 was changed to Car
2017-06-04 16:55 Bill Plith Data1 was changed to Foo
2017-06-04 16:55 Bill Plith Data9 was changed to Bar
2017-06-04 16:59 John Smith Data9 was changed to Car
2017-06-04 17:04 Bill Plith Data9 was changed to Bar
还有一些事项需要注意:
我认为这就是一切。提前感谢任何可以提供帮助的人,我还在学习SQL,所以如果我遗漏任何相关内容,请留下评论,我会填补空白!
答案 0 :(得分:1)
您可以将case
表达式与lag()
一起使用。假设这些值都不是NULL
:
select c.date, c.author,
stuff( ((case when data1 <> lag(data1) over (partition by date) then ', data1' else '' end) +
(case when data2 <> lag(data2) over (partition by date) then ', data2' else '' end) +
. . .
), 1, 2, '') as changes
from changes c;
可以修改它以处理NULL
值,尽管这会使表达式复杂化。
答案 1 :(得分:0)
可以使用UNPIVOT运算符和LAG函数的default
参数。
with
unp as(
select *
from @Changes
unpivot (
Data For DataNam in (Data1,Data2,Data3,Data4,Data5,Data6,Data7,Data8,Data9)
) u
),
a as(
select *,
lag(Data,1,Data) over(partition by DataNam order by [Date]) PrevData
from unp
)
select [Date], Author,DataNam+' was changed to '+Data Changes
from a
where Data!=PrevData
order by DataNam,[Date];
可以检查online。