必ずしも最も美しい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。