时态表:特定列仅更改版本详细信息

Dha*_*ngh 1 sql sql-server temporal-tables

需要有关查询时态表的帮助/想法。我在表上启用了 SQL 版本控制。该表当前有 15 列。

确切的要求是确定“OrderStatus”列更新了多少次以及谁在何时更新了它?我们只想查看“OrderStatus”列在特定日期与默认选择的所有其他列之间更新了多少次。

gve*_*vee 5

你的问题缺乏一些细节,所以我根据一些假设做了尝试。

[重新]创建代表表

IF Object_ID('dbo.orders', 'U') IS NOT NULL
  BEGIN
    ALTER TABLE dbo.orders SET (SYSTEM_VERSIONING = OFF);
  END
;
DROP TABLE IF EXISTS dbo.orders_history;
DROP TABLE IF EXISTS dbo.orders;

CREATE TABLE dbo.orders (
   OrderId     int         NOT NULL IDENTITY(9,37)
 , OrderStatus varchar(20) NOT NULL
 , UpdatedBy   varchar(20) NOT NULL
 , ValidFrom   datetime2 GENERATED ALWAYS AS ROW START
 , ValidTo     datetime2 GENERATED ALWAYS AS ROW END
 , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
 , CONSTRAINT pk_dbo_orders PRIMARY KEY (OrderId)
)
WITH (
  SYSTEM_VERSIONING = ON (
    HISTORY_TABLE = dbo.orders_history
  )
);
Run Code Online (Sandbox Code Playgroud)

创建样本数据

请注意,使用WAITFOR是为了提供事件之间的一些更具说明性的间隙。

INSERT INTO dbo.orders (OrderStatus, UpdatedBy)
  VALUES ('NEW', 'George')
       , ('NEW', 'George')
;
WAITFOR DELAY '00:00:02';

UPDATE dbo.orders
SET    OrderStatus = 'IN PROGRESS'
WHERE  OrderId = 9
;
WAITFOR DELAY '00:00:02';

-- Mark both orders as despatched
UPDATE dbo.orders
SET    OrderStatus = 'DESPATCHED'
;
WAITFOR DELAY '00:00:02';

-- Whoops, order #46 wasn't supposed to be marked as dispatched
UPDATE dbo.orders
SET    OrderStatus = 'IN PROGRESS'
WHERE  OrderId = 46
;
WAITFOR DELAY '00:00:02';

-- Mark it as in progress again, but changing the person who did the operation
UPDATE dbo.orders
SET    OrderStatus = 'IN PROGRESS'
     , UpdatedBy   = 'Not George'
WHERE  OrderId = 46
;
WAITFOR DELAY '00:00:02';

-- _Now_ it is despatched
UPDATE dbo.orders
SET    OrderStatus = 'DESPATCHED'
     , UpdatedBy   = 'George'
WHERE  OrderId = 46
;
Run Code Online (Sandbox Code Playgroud)

原始数据

我们来看看原始数据

SELECT OrderId
     , OrderStatus
     , UpdatedBy
     , ValidFrom
     , ValidTo
FROM   dbo.orders FOR SYSTEM_TIME ALL
ORDER
    BY OrderId
     , ValidFrom
;
Run Code Online (Sandbox Code Playgroud)
订单号 订单状态 更新者 有效日期 有效
9 新的 乔治 2021-02-17 10:27:35.1632525 2021-02-17 10:27:37.1719903
9 进行中 乔治 2021-02-17 10:27:37.1719903 2021-02-17 10:27:39.1852032
9 已发送 乔治 2021-02-17 10:27:39.1852032 9999-12-31 23:59:59.9999999
46 新的 乔治 2021-02-17 10:27:35.1632525 2021-02-17 10:27:39.1852032
46 已发送 乔治 2021-02-17 10:27:39.1852032 2021-02-17 10:27:41.1995704
46 进行中 乔治 2021-02-17 10:27:41.1995704 2021-02-17 10:27:43.2171042
46 进行中 不是乔治 2021-02-17 10:27:43.2171042 2021-02-17 10:27:45.2328908
46 已发送 仍然不是乔治 2021-02-17 10:27:45.2328908 9999-12-31 23:59:59.9999999

查询时间

; WITH _orders AS (
  SELECT OrderId
       , OrderStatus
       , UpdatedBy
       , ValidFrom
       , ValidTo
       , Lead(OrderStatus) OVER (PARTITION BY OrderId ORDER BY ValidFrom) AS NextOrderStatus
  FROM   dbo.orders FOR SYSTEM_TIME ALL
)
SELECT OrderId
     , OrderStatus
     , UpdatedBy
     , ValidFrom
FROM   _orders
WHERE  OrderStatus <> NextOrderStatus -- Only return records where the order status has changed
OR     NextOrderStatus IS NULL -- Include the "most recent" record in the results, always.
ORDER
    BY OrderId
     , ValidFrom
;
Run Code Online (Sandbox Code Playgroud)

结果

订单号 订单状态 更新者 有效日期
9 新的 乔治 2021-02-17 10:27:35.1632525
9 进行中 乔治 2021-02-17 10:27:37.1719903
9 已发送 乔治 2021-02-17 10:27:39.1852032
46 新的 乔治 2021-02-17 10:27:35.1632525
46 已发送 乔治 2021-02-17 10:27:39.1852032
46 进行中 不是乔治 2021-02-17 10:27:43.2171042
46 已发送 仍然不是乔治 2021-02-17 10:27:45.2328908