SQL查询以查找不同行之间的文本差异
我有一张类似以下的桌子:SQL查询以查找不同行之间的文本差异,sql,sql-server,Sql,Sql Server,我有一张类似以下的桌子: INITIAL TABLE ------------------------------------------------------- ID Date Author Data1 Data9 == ================ ========== ======= ... ======= 1 2017-06-04 16:47 John Smith
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
数据来自用户从中心源更改数据集。每当对任何数据字段进行更改时,都会将用户名、更改的日期时间以及所有数据字段值的刷新追加到表中
问题是,手动检查每一列以查看实际更改的位置非常繁琐。有时对一个字段进行更改,有时对多个字段进行更改,有时根本不进行更改(如果用户单击“保存更改”,但实际未进行任何更改,则仍会向表中添加新行)
我要做的是查询该表以生成类似于以下内容的结果:
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
还有一些事情需要注意:
- 如果初始表中的Data1-9在当前行和前一行之间未进行任何更改,则不应将任何行追加到更改表中
- 如果具有相同日期(和时间)和作者的更改可以合并到“更改”列中以逗号分隔的列表中,那么这也很理想
- 初始表中的ID将被排序,但某些ID将丢失。例如,id可以是1、2、3、4、7、8、10等等。值可能会丢失,但初始表上的顺序仍应基于ID(而不是日期)
我想这就是一切。提前感谢所有能够提供帮助的人,我仍在学习SQL,因此如果我遗漏了任何相关内容,请留下评论,我将填补空白 您可以使用带有
lag()
的巨型大小写表达式。假设所有值都不为空
:
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;
选择c.date、c.author、,
填充((当数据1滞后(数据1)超过(按日期划分)时,则',数据1'否则''结束)+
(当data2滞后(data2)超过(按日期划分)时,则',data2'else'结束)+
. . .
),1,2',)作为更改
来自变化c;
这可以修改为处理NULL
值,尽管这会使表达式有点复杂。可以使用UNPIVOT运算符和LAG函数的默认
参数
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];
这可以检查。使用插入后触发器更新新的更改列。您可以使用LAG函数检索前一行的ID以比较每一列。你将不得不使用一个巨大的案例陈述来连接你对每一个变更的评论。也许有人能想出更干净的解决方案。我最后用了一个变体来解决我的问题。感谢您的快速回复!