Voici un exemple de travail qui utilise UNPIVOT. C'est basé sur ma réponse à ma question Meilleure façon de partiellement UNPIVOT dans les paires en SQL
Cela a quelques fonctionnalités intéressantes.
-
L'ajout de champs supplémentaires est facile. Ajoutez simplement des valeurs aux clauses SELECT et UNPIVOT. Vous n'avez pas besoin d'ajouter de clauses UNION supplémentaires
-
La clause where
WHERE curr.value <> prev.value
ne change jamais quel que soit le nombre de champs ajoutés. -
Les performances sont étonnamment rapides.
-
Il est portable vers les versions actuelles d'Oracle si vous en avez besoin
SQL
Declare @Snapshots as table(
Sequence int,
DateTaken datetime,
[id] int,
field1 varchar(20),
field2 int)
INSERT INTO @Snapshots VALUES
(1, '2011-01-01', 1, 'Red', 2),
(2, '2011-01-01', 2, 'Blue', 10),
(3, '2011-02-01', 1, 'Green', 2),
(4, '2011-03-01', 1, 'Green' , 3),
(5, '2011-03-01', 2, 'Purple', 2),
(6, '2011-04-01', 1, 'Yellow', 2)
;WITH Snapshots (Sequence, DateTaken, ID, Field1, Field2, _Index)
AS
(
SELECT Sequence, DateTaken, ID, Field1, Field2, ROW_NUMBER() OVER (ORDER BY ID, Sequence) _Index
FROM @Snapshots
)
, data as(
SELECT
c._Index
, c.DateTaken
, c.ID
, cast(c.Field1 as varchar(max)) Field1
, cast(p.Field1 as varchar(max))Field1_Previous
, cast(c.Field2 as varchar(max))Field2
, cast(p.Field2 as varchar(max)) Field2_Previous
FROM Snapshots c
JOIN Snapshots p ON p.ID = c.ID AND (p._Index + 1) = c._Index
)
, fieldsToRows
AS (SELECT DateTaken,
id,
_Index,
value,
field
FROM data p UNPIVOT (value FOR field IN (field1, field1_previous,
field2, field2_previous) )
AS unpvt
)
SELECT
curr.DateTaken,
curr.ID,
curr.field,
prev.value previous,
curr.value 'current'
FROM
fieldsToRows curr
INNER JOIN fieldsToRows prev
ON curr.ID = prev.id
AND curr._Index = prev._Index
AND curr.field + '_Previous' = prev.field
WHERE
curr.value <> prev.value
Sortie
DateTaken ID field previous current
----------------------- ----------- --------- -------- -------
2011-02-01 00:00:00.000 1 Field1 Red Green
2011-03-01 00:00:00.000 1 Field2 2 3
2011-04-01 00:00:00.000 1 Field1 Green Yellow
2011-04-01 00:00:00.000 1 Field2 3 2
2011-03-01 00:00:00.000 2 Field1 Blue Purple
2011-03-01 00:00:00.000 2 Field2 10 2