SAT*_*D9X 5 sql-server query sql-server-2012 running-totals
--DROP TABLE Taco_Val;
CREATE TABLE Taco_Val
(
ID INT IDENTITY(1,1),
AuditID VARCHAR(5),
CreditID VARCHAR(10),
TS DATETIME,
Val BIT
);
INSERT INTO Taco_Val
VALUES
('a1', 1, '2018-08-09 19:24:39.823', 1),--> Started
('ac', 1, '2018-08-09 20:53:07.273', 0),
('as', 1, '2018-08-09 21:04:40.670', 0),
('a9', 1, '2018-08-09 21:14:17.660', 1),--> Another Seq
('av', 1, '2018-08-09 21:38:56.910', 1),
('ad', 1, '2018-08-09 21:48:46.180', 1),
('an', 1, '2018-08-09 22:00:15.650', 0),
('a4', 1, '2018-08-09 22:08:26.517', 1),-->Another Seq
('a8', 1, '2018-08-09 22:16:16.253', 0),
('a3', 1, '2018-08-09 22:16:24.247', 1),-->Another Seq
('ai', 1, '2018-08-09 22:18:59.143', 1),
('a3', 1, '2018-08-09 22:42:48.780', 1),
('ao', 1, '2018-08-09 22:51:21.117', 1),
('am', 1, '2018-08-09 23:01:13.777', 0),
('ac', 1, '2018-08-09 23:07:13.237', 0),
('ab', 1, '2018-08-09 23:16:38.257', 0),
('ay', 1, '2018-08-10 15:12:02.473', 1),-->Another Seq
('ae', 1, '2018-08-10 15:20:54.263', 0);
Run Code Online (Sandbox Code Playgroud)
--需要以下输出
AuditID CreditID StartTS Val Duration
a1 1 2018-08-09 19:24 1 100
a9 1 2018-08-09 21:14 1 46
a4 1 2018-08-09 22:08 1 8
a3 1 2018-08-09 22:16 1 60
ay 1 2018-08-10 15:12 1 8
Run Code Online (Sandbox Code Playgroud)
从 Val='1's 行开始(如果 Val='1's 是连续的,则忽略这些行,但计算 TS 上经过的持续时间(以分钟为单位),直到最后一个连续的 '0's 结束)
在 Val = '1' 的下一行重新开始
我希望这很清楚
这通常称为 GROUPING AND WINDOWS 解决方案。
基本上,您根据一些规则设置重置点,然后通过 SUMming 重置点设置组,最后使用聚合函数来获得所需的值。
Run Code Online (Sandbox Code Playgroud);WITH reset AS ( SELECT AuditID, CreditID, TS, Val, /* Next CASE returns 1 when: a) It is the first row of a partition b) Current Val=1 and previous = 0 Otherwise it returns 0 */ CASE WHEN Val=1 AND COALESCE(LAG(Val) OVER (PARTITION BY CreditID ORDER BY CreditID, TS), 0) = 0 THEN 1 ELSE 0 END AS Rst FROM Taco_Val ) , [group] AS ( SELECT AuditID, CreditID, TS, Val, /* Next SUM generates a cumulative sum of reset points. That is a correlative number for each partition */ SUM(Rst) OVER (PARTITION BY CreditID ORDER BY CreditID, TS) AS Grp FROM reset ) SELECT /* Next select returns, of every group, AuditID corresponding to the row with the minimum TS */ (SELECT AuditID FROM [group] WHERE CreditID = g.CreditID AND TS = MIN(g.TS)) AuditID, CreditID, MIN(TS) as StartTS, 1 as Val, DATEDIFF(MINUTE, MIN(TS), MAX(TS)) as Duration FROM [group] g GROUP BY CreditID, Grp; GO
审计ID | 信用ID | 开始TS | 瓦尔 | 期间 :------ | :------- | :------------------ | --: | -------: a1 | 1 | 09/08/2018 19:24:39 | 1 | 100 a9 | 1 | 09/08/2018 21:14:17 | 1 | 46 a4 | 1 | 09/08/2018 22:08:26 | 1 | 8 a3 | 1 | 09/08/2018 22:16:24 | 1 | 60 是| 1 | 10/08/2018 15:12:02 | 1 | 8
db<>在这里摆弄
您将在上一个小提琴上找到每个 CTE 的简要说明。