规则是:
仅当连续发生的两次错误之间的时间差小于10分钟时,每个股票代号才返回正在生成群集的ErrorCode链/群集。
在其他帖子中,我要求提供有关该任务的简化版本的帮助:每天分别产生错误链。最好的选择(以非常有效的方式工作)是STUFF + For XML Path。
我们可以将它用于更复杂的任务吗?还是应该使用游标来实现?
我会对此提出任何建议。
关于, 槟榔
DECLARE @table1 TABLE
(
[Ticket] INT,
[ErrorCode] CHAR(1),
[Date] DATETIME
);
INSERT INTO @table1
VALUES
(1, 'A', '01.07.2018 10:00:00'),
(1, 'B', '01.07.2018 10:02:00'),
(1, 'C', '01.07.2018 10:08:00'),
(1, 'A', '01.07.2018 10:30:09'),
(1, 'B', '01.07.2018 10:50:00'),
(1, 'D', '01.07.2018 10:55:00'),
(1, 'D', '01.07.2018 15:55:00'),
(1, 'D', '02.07.2018 10:55:00'),
(2, 'A', '20.10.2018 15:00:00'),
(2, 'C', '20.10.2018 17:00:00'),
(2, 'C', '20.10.2018 17:07:00'),
(2, 'A', '21.10.2018 09:00:00');
答案 0 :(得分:5)
一种选择是使用条件标志,然后通过窗口函数sum()聚合该标志
示例
;with cte as (
Select *
,Flg = case when datediff(MINUTE,lag(Date,1) over (Partition by Ticket Order By Date) , Date) > 10 then 1 else 0 end
From @table1
), cte1 as (
Select *
,Grp = sum(Flg) over (Partition By Ticket Order by Date)
From cte
)
Select Distinct
Grp
,Ticket
,Cluster = Stuff((Select '/' +ErrorCode From cte1 Where Ticket=A.Ticket and Grp=A.Grp For XML Path ('')),1,1,'')
From cte1 A
Order by Ticket,Grp
返回
Grp Ticket Cluster
0 1 A/B/C
1 1 A
2 1 B/D
3 1 D
4 1 D
0 2 A
1 2 C/C
2 2 A
编辑-请求的更新
;with cte as (
Select *
,Flg = case when datediff(MINUTE,lag(Date,1) over (Partition by Ticket Order By Date) , Date) > 10 then 1 else 0 end
From @table1
), cte1 as (
Select *
,Grp = sum(Flg) over (Partition By Ticket Order by Date)
From cte
)
Select Distinct
Grp
,Ticket
,LastDate = convert(date,max(Date) over (Partition By Ticket,Grp))
,Times = Stuff((Select ',' +format(Date,'HH:mm') From cte1 Where Ticket=A.Ticket and Grp=A.Grp For XML Path ('')),1,1,'')
,Cluster = Stuff((Select '/' +ErrorCode From cte1 Where Ticket=A.Ticket and Grp=A.Grp For XML Path ('')),1,1,'')
From cte1 A
Order by Ticket,Grp
返回
修改-调整效果
通过将XML/STUFF
迁移到最终/精简集,您可能会获得更高的性能。首先,字符串聚合是一个沉重的打击。我们只是减少了通话次数。
另一种选择是使用TEMP表而不是CTE。
;with cte as (
Select *
,Flg = case when datediff(MINUTE,lag(Date,1) over (Partition by Ticket Order By Date) , Date) > 10 then 1 else 0 end
From @table1
), cte1 as (
Select *
,Grp = sum(Flg) over (Partition By Ticket Order by Date)
From cte
), cte2 as (
Select Distinct
Grp
,Ticket
,LastDate = convert(date,max(Date) over (Partition By Ticket,Grp))
From cte1 A
)
Select *
,Times = Stuff((Select ',' +format(Date,'HH:mm') From cte1 Where Ticket=A.Ticket and Grp=A.Grp For XML Path ('')),1,1,'')
,Cluster = Stuff((Select '/' +ErrorCode From cte1 Where Ticket=A.Ticket and Grp=A.Grp For XML Path ('')),1,1,'')
From cte2 A
Order by Ticket,Grp
编辑-逐步
cte生成 注意Flg为1或0
cte1生成
cte2生成 注意,Grp是Flag的运行总计