Oracle - 从审计中获取多个条件的最新时间戳更新行 table
Oracle - Get latest timestamp updated rows for multiple criteria from audit table
我们有一个审计 table 跟踪不同 table 的变化以及 column_names、用户、时间戳、旧值和基于发票编号的新值.我需要检索一组特定的 tables 和特定发票编号的特定列集的最新审计数据(最后一个时间戳)。
Invoice_Number
Table_Name
Column_Name
Timestamp
User
Old_Value
New_Value
112
A
1
10-OCT-2021 12.00.00.111111
User1
7
6
112
B
1
11-OCT-2021 12.00.00.111111
User1
7
6
112
A
2
11-OCT-2021 12.00.00.111111
User1
7
6
114
B
1
12-OCT-2021 12.00.00.111111
User1
7
6
112
A
2
13-OCT-2021 12.00.00.111111
User1
7
6
122
B
2
13-OCT-2021 12.00.00.111111
User1
7
6
122
A
5
13-OCT-2021 12.00.00.111111
User1
7
6
112
A
2
15-OCT-2021 12.00.00.111111
User1
7
6
114
B
3
16-OCT-2021 12.00.00.111111
User1
7
6
112
B
2
18-OCT-2021 12.00.00.111111
User1
7
6
112
A
1
10-OCT-2021 12.00.00.111111
User1
7
6
142
B
1
11-OCT-2021 12.00.00.111111
User1
7
6
102
A
2
11-OCT-2021 12.00.00.111111
User1
7
6
184
B
1
12-OCT-2021 12.00.00.111111
User1
7
6
142
D
2
13-OCT-2021 12.00.00.111111
User1
7
6
118
C
2
18-OCT-2021 12.00.00.111111
User1
7
6
现在我需要获取发票编号 112 的最新更新记录,其中包含对 (Table A & Column 1, 2) 和 (Table B & column 1, 2).
我尝试使用排名,但不确定如何将其扩展到一列之外。
从 Oracle 12 开始,您可以使用 MATCH_RECOGNIZE
:
SELECT *
FROM (
SELECT *
FROM table_name
WHERE invoice_number = 112
AND table_name IN ('A', 'B')
AND column_name IN (1, 2)
)
MATCH_RECOGNIZE (
PARTITION BY /*invoice_number,*/ table_name, column_name
ORDER BY timestamp DESC
ALL ROWS PER MATCH
PATTERN (^ last_row)
DEFINE last_row AS 1 = 1
)
在早期版本中,可以使用ROW_NUMBER
解析函数:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY /*invoice_number,*/ table_name, column_name
ORDER BY timestamp DESC
) AS rn
FROM table_name t
WHERE invoice_number = 112
AND table_name IN ('A', 'B')
AND column_name IN (1, 2)
)
WHERE rn = 1;
注意:由于您只有一个 invoice_number
,因此不需要将其包含在 PARTITION BY
子句中;但是,如果您有多个 invoice_number
,那么您会想要。
其中,对于示例数据:
CREATE TABLE table_name (Invoice_Number, Table_Name, Column_Name, Timestamp, "USER", Old_Value, New_Value) AS
SELECT 112, 'A', 1, TIMESTAMP '2021-10-10 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'B', 1, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 2, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 114, 'B', 1, TIMESTAMP '2021-10-12 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 2, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 122, 'B', 2, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 122, 'A', 5, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 2, TIMESTAMP '2021-10-15 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 114, 'B', 3, TIMESTAMP '2021-10-16 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'B', 2, TIMESTAMP '2021-10-18 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 1, TIMESTAMP '2021-10-10 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 142, 'B', 1, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 102, 'A', 2, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 184, 'B', 1, TIMESTAMP '2021-10-12 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 142, 'D', 2, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 118, 'C', 2, TIMESTAMP '2021-10-18 12:00:00.111111', 'User1', 7, 6 FROM DUAL
输出:
TABLE_NAME
COLUMN_NAME
TIMESTAMP
INVOICE_NUMBER
USER
OLD_VALUE
NEW_VALUE
A
1
10-OCT-21 12.00.00.111111000
112
User1
7
6
A
2
15-OCT-21 12.00.00.111111000
112
User1
7
6
B
1
11-OCT-21 12.00.00.111111000
112
User1
7
6
B
2
18-OCT-21 12.00.00.111111000
112
User1
7
6
db<>fiddle here
我们有一个审计 table 跟踪不同 table 的变化以及 column_names、用户、时间戳、旧值和基于发票编号的新值.我需要检索一组特定的 tables 和特定发票编号的特定列集的最新审计数据(最后一个时间戳)。
Invoice_Number | Table_Name | Column_Name | Timestamp | User | Old_Value | New_Value |
---|---|---|---|---|---|---|
112 | A | 1 | 10-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
112 | B | 1 | 11-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
112 | A | 2 | 11-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
114 | B | 1 | 12-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
112 | A | 2 | 13-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
122 | B | 2 | 13-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
122 | A | 5 | 13-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
112 | A | 2 | 15-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
114 | B | 3 | 16-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
112 | B | 2 | 18-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
112 | A | 1 | 10-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
142 | B | 1 | 11-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
102 | A | 2 | 11-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
184 | B | 1 | 12-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
142 | D | 2 | 13-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
118 | C | 2 | 18-OCT-2021 12.00.00.111111 | User1 | 7 | 6 |
现在我需要获取发票编号 112 的最新更新记录,其中包含对 (Table A & Column 1, 2) 和 (Table B & column 1, 2).
我尝试使用排名,但不确定如何将其扩展到一列之外。
从 Oracle 12 开始,您可以使用 MATCH_RECOGNIZE
:
SELECT *
FROM (
SELECT *
FROM table_name
WHERE invoice_number = 112
AND table_name IN ('A', 'B')
AND column_name IN (1, 2)
)
MATCH_RECOGNIZE (
PARTITION BY /*invoice_number,*/ table_name, column_name
ORDER BY timestamp DESC
ALL ROWS PER MATCH
PATTERN (^ last_row)
DEFINE last_row AS 1 = 1
)
在早期版本中,可以使用ROW_NUMBER
解析函数:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY /*invoice_number,*/ table_name, column_name
ORDER BY timestamp DESC
) AS rn
FROM table_name t
WHERE invoice_number = 112
AND table_name IN ('A', 'B')
AND column_name IN (1, 2)
)
WHERE rn = 1;
注意:由于您只有一个 invoice_number
,因此不需要将其包含在 PARTITION BY
子句中;但是,如果您有多个 invoice_number
,那么您会想要。
其中,对于示例数据:
CREATE TABLE table_name (Invoice_Number, Table_Name, Column_Name, Timestamp, "USER", Old_Value, New_Value) AS
SELECT 112, 'A', 1, TIMESTAMP '2021-10-10 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'B', 1, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 2, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 114, 'B', 1, TIMESTAMP '2021-10-12 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 2, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 122, 'B', 2, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 122, 'A', 5, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 2, TIMESTAMP '2021-10-15 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 114, 'B', 3, TIMESTAMP '2021-10-16 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'B', 2, TIMESTAMP '2021-10-18 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 112, 'A', 1, TIMESTAMP '2021-10-10 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 142, 'B', 1, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 102, 'A', 2, TIMESTAMP '2021-10-11 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 184, 'B', 1, TIMESTAMP '2021-10-12 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 142, 'D', 2, TIMESTAMP '2021-10-13 12:00:00.111111', 'User1', 7, 6 FROM DUAL UNION ALL
SELECT 118, 'C', 2, TIMESTAMP '2021-10-18 12:00:00.111111', 'User1', 7, 6 FROM DUAL
输出:
TABLE_NAME COLUMN_NAME TIMESTAMP INVOICE_NUMBER USER OLD_VALUE NEW_VALUE A 1 10-OCT-21 12.00.00.111111000 112 User1 7 6 A 2 15-OCT-21 12.00.00.111111000 112 User1 7 6 B 1 11-OCT-21 12.00.00.111111000 112 User1 7 6 B 2 18-OCT-21 12.00.00.111111000 112 User1 7 6
db<>fiddle here