0

实际开始/结束时间列代表指令开始/结束日期。

但真正的指令会继续进行,直到 Min、Aim 或 Max 都发生变化。

所以,我需要按照 Min-Aim 和 Max 组按原始分组。

我不能直接将它们用作分组依据,因为 3 个月前和本月可以有相同的 Min-Aim-Max。

姓名 实际开始时间 实际结束时间 FLOW_SUM LIMS_AVG 目标 最大限度
DOI 10:15:25.793 18:30:53.027 5884 148 140 155 160
DOI 18:30:53.027 01:14:50.177 2170 149 140 155 160
DOI 01:14:50.177 11:18:58.383 3008 148 140 145 150

数据按 min-aim-max 分组

例如在屏幕截图中;行号 1,2 在同一条指令中,需要求和 flow_sum 和平均 lims_avg 行号 3 是一条指令本身 行号 4,5,6,7 是一条指令

不知何故,在按如下顺序排序后,我需要与前一个 raw 创建关系,然后是另一个 raw,直到找到不同的三元组 Min-Aim_Max。

我该如何查询?

4

2 回答 2

1

这是一种差距和孤岛问题。

有很多解决方案,这里有一个:

  • 使用计算每个岛屿的起点LAG
  • 使用窗口化为每个岛分配一个组 IDCOUNT
  • 按组 ID 分组并返回聚合
WITH StartPoints AS (
    SELECT *,
      IsStart = CASE WHEN
            LAG(dc.Min) OVER (PARTITION BY dc.Name ORDER BY dc.ActualStartTime) = dc.Min
        AND LAG(dc.Aim) OVER (PARTITION BY dc.Name ORDER BY dc.ActualStartTime) = dc.Aim
        AND LAG(dc.Max) OVER (PARTITION BY dc.Name ORDER BY dc.ActualStartTime) = dc.Max
        THEN NULL ELSE 1 END
    FROM dbo.vw_DOI_DEVIATION_CONSISTENCY dc
),
Groupings AS (
    SELECT *,
      GroupId = COUNT(dc.IsStart) OVER (PARTITION BY dc.Name ORDER BY dc.ActualStartTime ROWS UNBOUNDED PRECEDING)
    FROM StartPoints dc
)
SELECT
  dc.Name
  StartTime = MIN(dc.ActualStartTime),
  EndTime =   MAX(dc.ActualEndTime
  FLOW_SUM =  SUM(dc.FLOW_SUM),
  LIMS_AVG =  AVG(dc.LIMS_AVG),
  Min =       MIN(dc.Min),
  Aim =       MIN(dc.Aim),
  Max =       MIN(dc.Max)
FROM Groupings dc
GROUP BY dc.Name, dc.GroupId;
于 2021-08-20T13:08:45.923 回答
0

我不确定这是否有帮助,但现在没有更多时间了。我希望它有助于一些如何:

DECLARE @Table TABLE    
        (
                ActualStartTime     datetime
            ,   AimMin              int
            ,   AimCurrent          int
            ,   AimMax              int
        )   
;
INSERT INTO @Table
    VALUES  
    
    ('2020-12-31 10:15',    140,    155,    160)
,   ('2021-01-01 18:30',    140,    155,    160)
,   ('2021-01-02 01:14',    140,    145,    150) 
,   ('2021-01-02 11:18',    135,    140,    150)
,   ('2021-01-04 10:47',    135,    140,    150) 
,   ('2021-01-05 09:54',    135,    140,    150)
,   ('2021-01-05 16:36',    135,    140,    150) 
,   ('2021-01-05 19:33',    140,    155,    160)
,   ('2021-01-05 23:49',    140,    155,    160) 
,   ('2021-01-06 20:06',    140,    155,    160)
,   ('2021-01-07 10:32',    140,    155,    160) 
,   ('2021-01-07 16:53',    140,    155,    160)
,   ('2021-01-08 09:54',    140,    160,    160) 
;

;WITH Table1 AS
    (
        SELECT  TOP 100 PERCENT
                RowNo = RANK() OVER(PARTITION BY AimMin, AimCurrent, AimMax ORDER BY ActualStartTime)
            ,   *
        FROM    @Table
        ORDER BY ActualStartTime
    )
,   Table2  AS
    (
        SELECT  TOP 100 PERCENT
                RowNo = RANK() OVER(PARTITION BY AimMin, AimCurrent, AimMax ORDER BY ActualStartTime)
            ,   *
        FROM    @Table
        ORDER BY ActualStartTime
    )


SELECT  DISTINCT
        T1.* 
FROM    Table1  T1
JOIN    Table2  T2  ON T2.RowNo = T1.RowNo+1
WHERE   T2.RowNo = 3
    AND DATEDIFF(DAY,T1.ActualStartTime, T2.ActualStartTime) BETWEEN 0 AND 2
ORDER BY T1.ActualStartTime
于 2021-08-20T13:24:32.287 回答