首页 > 解决方案 > 比较记录并以文本形式获取差异

问题描述

表格1

+------+-----+-----+
| Name | RID | SID |
+------+-----+-----+
| A    |   1 |   9 |
| B    |   2 |   8 |
| C    |   3 |   7 |
| D    |   4 |   6 |
+------+-----+-----+

表 2

+------+-----+-----+
| Name | RID | SID |
+------+-----+-----+
| A    |   1 |   9 |
| B    |   4 |   8 |
| C    |   3 |   7 |
| D    |   4 |   9 |
+------+-----+-----+

我想比较两个表中的值并得到如下输出。我能够使用 EXCEPT找到不匹配的记录,但无法获得我预期的格式。

+------+-------------+
| Name |    Diff     |
+------+-------------+
| B    | RID: 2 -> 8 |
| D    | SID: 6 -> 9 |
+------+-------------+

我在下面尝试过:

Select Name ,  RID, SID from Table1
Except
Select Name ,  RID, SID from Table2

标签: sqlsql-server

解决方案


您可以使用此查询来获得所需的结果。它在任何对给定具有不同或值的JOIN行上Table1,然后使用(自 2017 版起可用)来获得所需的值。请注意,此代码还将处理两者不同的情况:Table2RIDSIDNameCONCAT_WSDiff RIDSID

SELECT t1.Name,
       CONCAT_WS(', ',
                 CASE WHEN t1.RID != t2.RID THEN CONCAT('RID: ', t1.RID, ' -> ', t2.RID) END,
                 CASE WHEN t1.SID != t2.SID THEN CONCAT('SID: ', t1.SID, ' -> ', t2.SID) END
                 ) AS Diff
FROM Table1 t1
JOIN Table2 t2 ON t2.Name = t1.Name 
              AND (t2.RID != t1.RID OR t2.SID != t1.SID)

如果您在 2017 年之前运行 SQL Server 并且没有CONCAT_WS,则可以使用此查询,该查询仅使用CONCAT

SELECT t1.Name,
       CONCAT(CASE WHEN t1.RID != t2.RID THEN CONCAT('RID: ', t1.RID, ' -> ', t2.RID) END,
              CASE WHEN t1.RID != t2.RID AND t1.SID != t2.SID THEN ', ' END,
              CASE WHEN t1.SID != t2.SID THEN CONCAT('SID: ', t1.SID, ' -> ', t2.SID) END
              ) AS Diff
FROM Table1 t1
JOIN Table2 t2 ON t2.Name = t1.Name 
              AND (t2.RID != t1.RID OR t2.SID != t1.SID)

输出(用于我的扩展演示):

Name    Diff
B       RID: 2 -> 4
D       SID: 6 -> 9
E       RID: 4 -> 6, SID: 6 -> 7

SQLFiddle 上的演示


推荐阅读