不一定是最漂亮的 SQL,但这将使用非常通用的CASE
逻辑来完成。
由于它是一个审计表,因此它假定修订中没有空白以简化事情。
SELECT
CASE
WHEN ea1."First_name" <> ea2."First_name" THEN 'First_Name'
WHEN ea1."Last_Name" <> ea2."Last_Name" THEN 'Last_Name'
WHEN ea1."Gender" <> ea2."Gender" THEN 'Gender'
WHEN ea1."Position" <> ea2."Position" THEN 'Position' END "Column_name",
ea2."Employee_id", ea2."Revision",
CASE
WHEN ea1."First_name" <> ea2."First_name" THEN ea1."First_name"
WHEN ea1."Last_Name" <> ea2."Last_Name" THEN ea1."Last_Name"
WHEN ea1."Gender" <> ea2."Gender" THEN ea1."Gender"
WHEN ea1."Position" <> ea2."Position" THEN ea1."Position" END "Old_Value",
CASE
WHEN ea1."First_name" <> ea2."First_name" THEN ea2."First_name"
WHEN ea1."Last_Name" <> ea2."Last_Name" THEN ea2."Last_Name"
WHEN ea1."Gender" <> ea2."Gender" THEN ea2."Gender"
WHEN ea1."Position" <> ea2."Position" THEN ea2."Position" END "New_Value"
FROM EMPLOYEE_AUDIT ea1
JOIN EMPLOYEE_AUDIT ea2
ON ea1."Employee_id" = ea2."Employee_id"
AND ea1."Revision" = ea2."Revision" -1
一个用于测试的 SQLFiddle。
编辑:既然你问了,这是一个使用的版本LAG
,没有很大的改进;
WITH cte AS (
SELECT "Employee_id", "Revision", "First_name" fn, "Last_Name" ln,
"Gender" g, "Position" p,
LAG("First_name", 1) OVER
(PARTITION BY "Employee_id" ORDER BY "Revision") fn2,
LAG("Last_Name", 1) OVER
(PARTITION BY "Employee_id" ORDER BY "Revision") ln2,
LAG("Gender", 1) OVER
(PARTITION BY "Employee_id" ORDER BY "Revision") g2,
LAG("Position",1) OVER
(PARTITION BY "Employee_id" ORDER BY "Revision") p2
FROM EMPLOYEE_AUDIT
)
SELECT
CASE
WHEN fn <> fn2 THEN 'First_Name' WHEN ln <> ln2 THEN 'Last_Name'
WHEN g <> g2 THEN 'Gender' WHEN p <> p2 THEN 'Position'
END "Column_name", "Employee_id", "Revision",
CASE
WHEN fn <> fn2 THEN fn2 WHEN ln <> ln2 THEN ln2
WHEN g <> g2 THEN g2 WHEN p <> p2 THEN p2
END "Old_Value",
CASE
WHEN fn <> fn2 THEN fn WHEN ln <> ln2 THEN ln
WHEN g <> g2 THEN g WHEN p <> p2 THEN p
END "New_Value"
FROM cte
WHERE fn2 IS NOT NULL;
另一个 SQLfiddle。