Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Làm cách nào tôi có thể viết một truy vấn để trích xuất các thay đổi riêng lẻ từ ảnh chụp nhanh của dữ liệu?

Đây là một mẫu làm việc sử dụng UNPIVOT. Nó dựa trên câu trả lời của tôi cho câu hỏi của tôi Cách tốt hơn để UNPIVOT một phần trong các cặp trong SQL

Điều này có một số tính năng hay.

  1. Thêm các trường bổ sung rất dễ dàng. Chỉ cần thêm giá trị vào mệnh đề SELECT và UNPIVOT. Bạn không phải thêm các điều khoản UNION bổ sung

  2. Mệnh đề where WHERE curr.value <> prev.value không bao giờ thay đổi bất kể có bao nhiêu trường được thêm vào.

  3. Hiệu suất nhanh đáng ngạc nhiên.

  4. Có thể di chuyển đến các phiên bản Oracle hiện tại nếu bạn cần

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

Đầu ra

Trường
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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tạo Cơ sở dữ liệu SQL Server với SQLOPS

  2. Tạo một thủ tục được lưu trữ thông qua C #

  3. Cách tạo bảng Temp với SELECT * INTO tempTable FROM CTE Query

  4. cách đặt dữ liệu của bạn theo chiều ngang

  5. Chia một giá trị cột thành nhiều giá trị cột