【问题标题】:TSQL to compare data and return results on different rowsTSQL 比较数据并返回不同行的结果
【发布时间】:2021-09-09 04:31:35
【问题描述】:

我正在尝试编写一个 SQL 查询来比较两个表中的相同数据,一个是原始数据,另一个是该数据的更新版本。我想比较两个数据集的任何更改并返回这些更改。我已经设法做到了,但我想在不同的行中返回结果,而不是在同一行中。 所以目前我的结果集如下所示:

Type of Change Original Staff Number New Staff Number Original Name New Name Original Title New Title
UPDATE 1234 1234 Joe Smyth Joe Smith Mr Mr
UPDATE 4321 4321 Sally Green Sally Green Ms Mrs

我可以看到它返回了两名员工,他们的详细信息发生了变化。 Joe Smyth 的名字有误,已更正为 Joe Smith,而 Sally Green 已从 Ms 变为 Mrs。 但是,我希望我返回的数据集是这种形状:

Type of Change Data Source Staff Number Name Title
UPDATE Original Data 1234 Joe Smyth Mr
UPDATE New Data 1234 Joe Smith Mr
UPDATE Original Data 4321 Sally Green Ms
UPDATE New Data 4321 Sally Green Mrs

这是我以前这样说的查询:

首先我返回了对临时表的任何更改。

    SELECT      b.StaffNumber
    INTO        #StaffNumbers
    FROM        OriginalData a
    LEFT JOIN   NewData b
    ON          a.StaffNumber = b.StaffNumber
    AND         (a.Name != b.Name
    OR          a.Title != b.Title)
    WHERE       b.StaffNumber IS NOT NULL

然后使用 UNION 从不同的数据集中提取我想要的数据来加入它们:

    SELECT  *
    FROM    (
                SELECT      'UPDATE' as [Type Of Change],
                            'Original Data' as [Data Source],
                            StaffNumber as [Staff Number],
                            Name,
                            Title
                FROM        App_Person a
                INNER JOIN  #GmcNumber b
                ON          a.StaffNumber = b.StaffNumber
                UNION
                SELECT      'UPDATE' as [Type Of Change],
                            'New Data' as [Data Source],
                            a.StaffNumber as [Staff Number],
                            Name,
                            Title,
                FROM        PersonExtract a
                INNER JOIN  #StaffNumbers b
                ON          a.StaffNumber = b.StaffNumber
            ) sub1
    ORDER BY [Staff Number]

所以当我得到我想要的结果时,我想知道是否有比我上面所做的更聪明的方法来做到这一点。如果有人有任何想法/建议。

非常感谢!!

【问题讨论】:

  • 在 SO 上多次询问了关于比较 2 个表中数据的类似问题
  • 如果员工有超过 1 个更新怎么办?
  • 您是否还希望行出现在旧集中而不出现在更新集中?
  • @Squirrel 每个员工只有一行。那一行可能包含许多更改,例如改名,改名。但我更想知道是否有比我目前使用的方式更复杂的 SQL 解决方案来显示两行结果。

标签: sql-server tsql


【解决方案1】:

您可以使用CROSS APPLY 将旧数据和新数据从联接中转出。

不需要临时表。

SELECT
  'UPDATE' AS [Type of Change],
  a.StaffNumber,
  v.[Data Source],
  v.Name,
  v.Title
FROM OriginalData a
JOIN NewData b ON a.StaffNumber = b.StaffNumber
    AND (a.Name != b.Name OR a.Title != b.Title)
CROSS APPLY (
  SELECT 'Original Data' as [Data Source], a.Name, a.Title
  UNION ALL
  SELECT 'New Data', b.Name, b.Title
) v

如果你想要所有的差异,你需要一个FULL JOIN

SELECT
  CASE
    WHEN a.StaffNumber IS NOT NULL AND b.StaffNumber IS NOT NULL
      THEN 'UPDATE'
    WHEN a.StaffNumber IS NULL
      THEN 'INSERT'
    ELSE 'DELETE'
    END AS [Type of Change],
  ISNULL(a.StaffNumber, b.StaffNumber) AS StaffNumber,
  v.[Data Source],
  v.Name,
  v.Title
FROM OriginalData a
FULL JOIN NewData b ON a.StaffNumber = b.StaffNumber
    AND NOT EXISTS (SELECT a.Name, a.Title INTERSECT SELECT b.Name, b.Title)
CROSS APPLY (
  SELECT 'Original Data' as [Data Source], a.Name, a.Title
  WHERE a.StaffNumber IS NOT NULL
  UNION ALL
  SELECT 'New Data', b.Name, b.Title
  WHERE b.StaffNumber IS NOT NULL
) v

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-02
    • 2015-08-04
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 2019-05-16
    相关资源
    最近更新 更多