【问题标题】:How to find the changes happened between rows?如何找到行之间发生的变化?
【发布时间】:2019-10-04 14:23:18
【问题描述】:

我有两张表需要找出它们之间的区别。

所需的是一个汇总了哪些字段已更改的表格(忽略 id 列)。另外,我不知道哪些列发生了变化。

例如源表[已更改的字段为{name}、{location}; {id} 被忽略]

id || name || location || description

1 || aaaa || ddd || abc

2 || bbbb || eee || abc

例如输出表 [输出 {name}、{location} 已更改]

Table_name || Field_changed || field_was || field_now

Source table || name || aaaa ||  bbbb

Source table || location || ddd || eee

我尝试使用lag();但这只会给我选择的列。最终我想查看所有列中的所有更改,因为我不确定哪些列发生了更改。

另外请注意,该表有大约 150 列 - 所以最大的问题之一是如何找到发生变化的列

【问题讨论】:

  • 您错误地标记了问题。是 Oracle 还是 MySQL?
  • 我的意思是甲骨文。
  • 我想你想要的在这里得到了回答。 Check this

标签: sql oracle select


【解决方案1】:

由于您的表可以在单行中包含多个更改,并且需要在结果中计算为多行,因此我创建了一个查询以分别合并它们,如下所示:

WITH DATAA(ID, NAME, LOCATION, DESCRIPTION)
AS
(SELECT 1, 'aaaa', 'ddd', 'abc' FROM DUAL UNION ALL
SELECT 2, 'bbbb', 'eee', 'abc' FROM DUAL),

-- YOUR QUERY WILL START FROM HERE
CTE AS (SELECT NAME, 
LAG(NAME,1) OVER (ORDER BY ID) PREV_NAME,
LOCATION, 
LAG(LOCATION,1) OVER (ORDER BY ID) PREV_LOCATION,
DESCRIPTION, 
LAG(DESCRIPTION,1) OVER (ORDER BY ID) PREV_DESCRIPTION 
FROM DATAA)
--
SELECT
    'Source table' AS TABLE_NAME,
    FIELD_CHANGED,
    FIELD_WAS,
    FIELD_NOW
FROM
    (
        SELECT
            'Name' AS FIELD_CHANGED,
            PREV_NAME        AS FIELD_WAS,
            NAME   AS FIELD_NOW
        FROM
            CTE
        WHERE
            NAME <> PREV_NAME
        UNION ALL
        SELECT
            'location' AS FIELD_CHANGED,
            PREV_LOCATION        AS FIELD_WAS,
            LOCATION   AS FIELD_NOW
        FROM
            CTE
        WHERE
            LOCATION <> PREV_LOCATION
        UNION ALL
        SELECT
            'description' AS FIELD_CHANGED,
            PREV_DESCRIPTION        AS FIELD_WAS,
            DESCRIPTION   AS FIELD_NOW
        FROM
            CTE
        WHERE
            DESCRIPTION <> PREV_DESCRIPTION
    );

输出:

DEMO

干杯!!

【讨论】:

  • 谢谢!很有用。但是我可能应该更具体 - 该表的列比这四个多得多。我是否正确地说这段代码仅适用于有限数量的列?
  • 是的,你是对的。因为你的表结构是这样的。如果你对 PL/SQL 代码没问题,那么你可以在评论中尝试@IMS 描述的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-14
  • 2015-05-31
  • 1970-01-01
  • 2020-06-05
  • 1970-01-01
  • 2016-07-12
相关资源
最近更新 更多