首页 > 解决方案 > SQL查询以查找不同行之间的文本差异

问题描述

我有一个类似于以下的表:

                     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,所以如果我遗漏了任何相关内容,请发表评论,我会填补空白!

标签: sqlsql-server

解决方案


您可以使用带有 的巨型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值,尽管这会使表达式有点复杂。


推荐阅读