sql >> Databáze >  >> RDS >> Sqlserver

SQL:Vraťte audit pro záznamy pro každý sloupec

Pokud jsem nic nepřehlédl:

WITH ranked AS (
  SELECT
    ChangeDate,
    ColPK,
    Col1,
    Col2,
    Col3,
    Col4,
    Col5,
    OverallRank = ROW_NUMBER() OVER (PARTITION BY ColPK       ORDER BY ChangeDate),
    Col1Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col1 ORDER BY ChangeDate),
    Col2Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col2 ORDER BY ChangeDate),
    Col3Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col3 ORDER BY ChangeDate),
    Col4Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col4 ORDER BY ChangeDate),
    Col5Rank    = ROW_NUMBER() OVER (PARTITION BY ColPK, Col5 ORDER BY ChangeDate)
  FROM AuditTable
)
, ranked2 AS (
  SELECT
    ChangeDate,
    ColPK,
    Col1,
    Col2,
    Col3,
    Col4,
    Col5,
    Col1Group = RANK() OVER (PARTITION BY ColPK, Col1 ORDER BY OverallRank - Col1Rank),
    Col2Group = RANK() OVER (PARTITION BY ColPK, Col2 ORDER BY OverallRank - Col2Rank),
    Col3Group = RANK() OVER (PARTITION BY ColPK, Col3 ORDER BY OverallRank - Col3Rank),
    Col4Group = RANK() OVER (PARTITION BY ColPK, Col4 ORDER BY OverallRank - Col4Rank),
    Col5Group = RANK() OVER (PARTITION BY ColPK, Col5 ORDER BY OverallRank - Col5Rank),
    Col1Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col1, OverallRank - Col1Rank ORDER BY ChangeDate),
    Col2Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col2, OverallRank - Col2Rank ORDER BY ChangeDate),
    Col3Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col3, OverallRank - Col3Rank ORDER BY ChangeDate),
    Col4Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col4, OverallRank - Col4Rank ORDER BY ChangeDate),
    Col5Rank = ROW_NUMBER() OVER (PARTITION BY ColPK, Col5, OverallRank - Col5Rank ORDER BY ChangeDate)
  FROM ranked
),
unpivoted AS (
  SELECT
    r.ChangeTime,
    r.ColPK,
    x.ColName,
    ColRank = CASE x.Colname
      WHEN 'Col1' THEN Col1Group
      WHEN 'Col2' THEN Col2Group
      WHEN 'Col3' THEN Col3Group
      WHEN 'Col4' THEN Col4Group
      WHEN 'Col5' THEN Col5Group
    END,
    Value = CASE x.Colname
      WHEN 'Col1' THEN CONVERT(nvarchar(100), r.Col1)
      WHEN 'Col2' THEN CONVERT(nvarchar(100), r.Col2)
      WHEN 'Col3' THEN CONVERT(nvarchar(100), r.Col3)
      WHEN 'Col4' THEN CONVERT(nvarchar(100), r.Col4)
      WHEN 'Col5' THEN CONVERT(nvarchar(100), r.Col5)
    END
  FROM ranked2 r
    INNER JOIN (VALUES ('Col1'), ('Col2'), ('Col3'), ('Col4'), ('Col5')) x (ColName)
      ON x.ColName = 'Col1' AND Col1Rank = 1
      OR x.ColName = 'Col2' AND Col2Rank = 1
      OR x.ColName = 'Col3' AND Col3Rank = 1
      OR x.ColName = 'Col4' AND Col4Rank = 1
      OR x.ColName = 'Col5' AND Col5Rank = 1
)
SELECT
  new.ChangeTime,
  new.ColPK,
  new.ColName,
  old.Value AS OldValue,
  new.Value AS NewValue
FROM unpivoted new
  LEFT JOIN unpivoted old
    ON new.ColPK   = old.ColPK
   AND new.ColName = old.ColName
   AND new.ColRank = old.ColRank + 1

V zásadě jde o to, seřadit souvislé skupiny identických hodnot a vybrat první výskyty každé hodnoty. To se provádí pro každý sloupec, jehož hodnoty jsou auditovány, a sloupce jsou v procesu unpivoted. Poté je neotočná sada řádků spojena sama se sebou, tj. pro každý název PK a sloupce je každý řádek porovnán se svým předchůdcem (na základě hodnocení), aby se získala stará hodnota ve stejném řádku pro konečnou sadu výsledků.



  1. fulltextový dotaz v joomle

  2. MySQL a PHP Neočekávaná T_Variable

  3. Nástroj pro optimalizaci mysql

  4. jak získat oznámení z databáze s různými typy oznámení