您的问题缺少一些细节,所以我根据一些假设进行了尝试。
[re-]创建代表表
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
)
);
创建示例数据
请注意,使用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
;
原始数据
让我们来看看原始数据
SELECT OrderId
, OrderStatus
, UpdatedBy
, ValidFrom
, ValidTo
FROM dbo.orders FOR SYSTEM_TIME ALL
ORDER
BY OrderId
, ValidFrom
;
| OrderId |
OrderStatus |
UpdatedBy |
ValidFrom |
ValidTo |
| 9 |
NEW |
George |
2021-02-17 10:27:35.1632525 |
2021-02-17 10:27:37.1719903 |
| 9 |
IN PROGRESS |
George |
2021-02-17 10:27:37.1719903 |
2021-02-17 10:27:39.1852032 |
| 9 |
DESPATCHED |
George |
2021-02-17 10:27:39.1852032 |
9999-12-31 23:59:59.9999999 |
| 46 |
NEW |
George |
2021-02-17 10:27:35.1632525 |
2021-02-17 10:27:39.1852032 |
| 46 |
DESPATCHED |
George |
2021-02-17 10:27:39.1852032 |
2021-02-17 10:27:41.1995704 |
| 46 |
IN PROGRESS |
George |
2021-02-17 10:27:41.1995704 |
2021-02-17 10:27:43.2171042 |
| 46 |
IN PROGRESS |
Not George |
2021-02-17 10:27:43.2171042 |
2021-02-17 10:27:45.2328908 |
| 46 |
DESPATCHED |
Still Not George |
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
;
结果
| OrderId |
OrderStatus |
UpdatedBy |
ValidFrom |
| 9 |
NEW |
George |
2021-02-17 10:27:35.1632525 |
| 9 |
IN PROGRESS |
George |
2021-02-17 10:27:37.1719903 |
| 9 |
DESPATCHED |
George |
2021-02-17 10:27:39.1852032 |
| 46 |
NEW |
George |
2021-02-17 10:27:35.1632525 |
| 46 |
DESPATCHED |
George |
2021-02-17 10:27:39.1852032 |
| 46 |
IN PROGRESS |
Not George |
2021-02-17 10:27:43.2171042 |
| 46 |
DESPATCHED |
Still Not George |
2021-02-17 10:27:45.2328908 |