在特定条件下Raws成为String

arh*_*typ 2 t-sql

基于下面提供的代码,我需要实现所需的表: 在此输入图像描述

规则是:

每个Ticker返回ErrorCode链/集群,只有当错误连续发生的时间差小于10分钟时才会生成集群.

在其他帖子下,我正在寻求关于该任务的更简单版本的协助:单独为每一天生成错误链.最好的选择(以非常有效的方式工作)有STUFF + For XML Path.

我们能否以某种方式使用它 - 更复杂的任务?或者替代地,它应该用游标来实现?

我将不胜感激.

此致,Arek

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');
Run Code Online (Sandbox Code Playgroud)

Joh*_*tti 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
Run Code Online (Sandbox Code Playgroud)

返回

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
Run Code Online (Sandbox Code Playgroud)

编辑 - 请求的更新

;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
Run Code Online (Sandbox Code Playgroud)

返回

在此输入图像描述

编辑 - 调整性能

通过迁移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
Run Code Online (Sandbox Code Playgroud)

编辑 - 循序渐进

cte Generates Notice Flg为1或0

在此输入图像描述

cte1生成

在此输入图像描述

cte2生成通知Grp是标志的运行总计

在此输入图像描述