对于循环或while循环SQL连续日期

时间:2017-11-24 16:20:37

标签: sql sql-server tsql sql-server-2012

我有一张表告诉我们运行的日期以及是否失败。 我需要一个查询,它将获得最后一个失败的日期,然后是它失败的最后一个连续日期,所以基本上是失败的开始日期到日期连续的失败的结束日期。

   EntityID |    Date     | Entities | Loaded | Status |
    B0034     2017-11-16       54       full    Success
    B0033     2017-11-16       54       full    Success
    B0034     2017-11-15       54       full    Success
    B0033     2017-11-15       58       full    Failed   
    B0035     2017-11-15       88       full    Success
    B0033     2017-11-14       56       full    Failed
    B0036     2017-11-15       50       full    Success
    B0033     2017-11-13       56       full    Failed
    B0037     2017-11-15       50       full    Success
    B0033     2017-11-12       34       full    Success
    B0034     2017-11-14       50       full    Success
    B0035     2017-11-14       38       full    Success
    B0033     2017-11-11       50       full    Success
    B0037     2017-11-14       59       full    Success
    B0033     2017-11-10       11       full    Failed
    B0037     2017-11-13       67       full    Success
    B0037     2017-11-12       78       full    Success
    B0033     2017-11-09       32       full    Failed
    B0033     2017-11-08       99       full    Failed 
    B0033     2017-11-17       33       full    Success

在这种情况下对于ID B0033,我需要:

  EntityID |    Date     | Entities | Loaded | Status |
    B0033     2017-11-15       58       full    Failed  
    B0033     2017-11-13       56       full    Failed 

由于B0033从13日到15日连续失败

示例DDL如下:

CREATE TABLE #Sample (EntityID varchar(5),
                      [Date] date,
                      [Entities] int,
                      Loaded varchar(4),
                      [Status] varchar(7));

INSERT INTO #Sample
VALUES
    ('B0034','20171116',54,'full','Success'),
    ('B0033','20171116',54,'full','Success'),
    ('B0034','20171115',54,'full','Success'),
    ('B0033','20171115',58,'full','Failed'),  
    ('B0035','20171115',88,'full','Success'),
    ('B0033','20171114',56,'full','Failed'),
    ('B0036','20171115',50,'full','Success'),
    ('B0033','20171113',56,'full','Failed'),
    ('B0037','20171115',50,'full','Success'),
    ('B0033','20171112',34,'full','Success'),
    ('B0034','20171114',50,'full','Success'),
    ('B0035','20171114',38,'full','Success'),
    ('B0033','20171111',50,'full','Success'),
    ('B0037','20171114',59,'full','Success'),
    ('B0033','20171110',11,'full','Failed'),
    ('B0037','20171113',67,'full','Success'),
    ('B0037','20171112',78,'full','Success'),
    ('B0033','20171109',32,'full','Failed'),
    ('B0033','20171108',99,'full','Failed'),
    ('B0033','20171117',33,'full','Success');
GO

SELECT *
FROM #Sample;
GO

DROP TABLE #Sample;

2 个答案:

答案 0 :(得分:2)

我认为这就是你所追求的:

WITH Groups AS(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY EntityID ORDER BY Date ASC) - 
           ROW_NUMBER() OVER (PARTITION BY EntityID, [Status] ORDER BY Date ASC) AS Grp
    FROM #Sample),
TopBottom AS(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY EntityID, Grp ORDER BY Date ASC) AS RNAsc,
           ROW_NUMBER() OVER (PARTITION BY EntityID, Grp ORDER BY Date DESC) AS RNDesc,
           DENSE_RANK() OVER (PARTITION BY EntityID ORDER BY Grp DESC) AS Ranking
    FROM Groups
    WHERE [Status] = 'Failed')
SELECT EntityID,
       [Date],
       Entities,
       Loaded,
       [Status]
FROM TopBottom
WHERE (RNAsc = 1 OR RNDesc = 1)
  AND Ranking = 1;

答案 1 :(得分:1)

对于OP在上述评论中的其他请求(对我的初步答案)。这应该可以满足您的需求。请注意,这只返回实体的一个值。您 应该能够找出如何根据您的需要进行更改。

WITH Groups AS(
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY EntityID ORDER BY Date ASC) - 
           ROW_NUMBER() OVER (PARTITION BY EntityID, [Status] ORDER BY Date ASC) AS Grp
    FROM #Sample),
Latest AS (
    SELECT *,
           MIN([date]) OVER (PARTITION BY Grp) As Start_Date,
           MAX([date]) OVER (PARTITION BY Grp) As End_Date,
           ROW_NUMBER() OVER (PARTITION BY EntityID ORDER BY [date] DESC) AS RN
    FROM Groups
    WHERE [Status] = 'Failed')
SELECT EntityID,
       Start_Date, End_Date,
       Entities,
       Loaded,
       [Status]
FROM Latest
WHERE RN = 1;