SQL查询以重新分组审计信息

huangapple go评论53阅读模式
英文:

Sql query to regroup audit information

问题

DataId Time Username Column Old value New value
1 2023-01-01 12:00:00 User1 DataC Bazar2 Bazar
1 2023-01-01 06:00:00 User1 DataB Much2 Much
英文:

I have a SQL Server database where there is an history table containing a record each time the said record, in another table, changes.

The source data table:

Id DataA DataB DataC
1 Truc Much Bazar

The history table:

DataId Time Username DataA DataB DataC
1 2023-01-01 12:00:00 User1 Truc Much Bazar
1 2023-01-01 06:00:00 User1 Truc Much Bazar2
1 2023-01-01 00:00:00 User1 Truc Much2 Bazar2

Meaning the record 1 of the data table has been updated 3 times by user "User1", He changed "Much2" to "Much" and "Bazar2" to "Bazar". The last record (first line) being the current state.

I would like to make a query that shows the audit in a way we can see which column has been updated, with the old value, the new one, and by who and when

In this example, it will be like this:

DataId Time Username Column Old value New value
1 2023-01-01 12:00:00 User1 DataC Bazar2 Bazar
2 2023-01-01 06:00:00 User1 DataB Much2 Much

I'm clearly not an expert in SQL, and I don't really know how to handle this. Any help will be appreciated

答案1

得分: 3

以下是您要的翻译内容:

您可以将数据列解析为行,然后使用窗口函数来识别值的变化:

select dataid, time, username, col, lag_val as old_value, val as new_value
from (
    select t.*, v.*,
        lag(val, 1, val) over(partition by dataid, col order by time) lag_val
    from mytable t
    cross apply ( values ('DataA', DataA), ('DataB', DataB), ('DataC', DataC) ) v(col, val)
) t
where val <> lag_val
order by dataid, time
dataid time username col old_value new_value
1 2023-01-01 06:00:00.000 User1 DataB Much2 Much
1 2023-01-01 12:00:00.000 User1 DataC Bazar2 Bazar

[fiddle](https://dbfiddle.uk/OJ6l-4IR)

<details>
<summary>英文:</summary>

You can unpivot your data columns to rows, then use window functions to identify values that changed:


    select dataid, time, username, col, lag_val as old_value, val as new_value
    from (
        select t.*, v.*,
            lag(val, 1, val) over(partition by dataid, col order by time) lag_val
        from mytable t
        cross apply ( values (&#39;DataA&#39;, DataA), (&#39;DataB&#39;, DataB), (&#39;DataC&#39;, DataC) ) v(col, val)
    ) t
    where val &lt;&gt; lag_val
    order by dataid, time

| dataid | time | username | col | old\_value | new\_value |
| ------:|:----|:--------|:---|:---------|:---------|
| 1 | 2023-01-01 06:00:00.000 | User1 | DataB | Much2 | Much |
| 1 | 2023-01-01 12:00:00.000 | User1 | DataC | Bazar2 | Bazar |

[fiddle](https://dbfiddle.uk/OJ6l-4IR)

</details>



huangapple
  • 本文由 发表于 2023年3月31日 23:34:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900315.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定