如何获得给定条件的连续行

时间:2018-12-21 15:33:19

标签: sql sql-server common-table-expression

我有一张看起来像这样的桌子

    WeekId     PassesCondition
----------------------------------
      1              1
      2              0
      3              0
      4              1
      5              1
      6              1

我需要编写一个查询,该查询从条件已通过的最大值WeekId开始算起连续几周。

我已经进行了一些搜索,似乎可能需要对CTEROW_NUMBER()进行一些操作。我已经尝试了一些方法,但是结果甚至都不值得发布为“到目前为止我已经尝试过的”。

输出应该只是从条件Max(WeekId)起经过了几周的计数。例如1、2、5等

3 个答案:

答案 0 :(得分:2)

假设条件仅为01

select count(*)
from t
where t.weekid > (select max(t2.weekid) from t t2 where t2.passesCondition = 0) or
      not exists (select 1 from t t2 where t2.passesCondition = 0);

如果您知道存在带有passesCondition = 0的行,则不需要第二个条件。

如果您喜欢使用窗口功能,也可以使用累积反向最小值来实现:

select count(*)
from (select t.*,
             min(passesCondition) over (order by weekid desc) as running_min
      from t
     ) t
where running_min = 1;

或者,可以使用not exists

select count(*)
from t
where not exists (select 1
                  from t t2
                  where t2.weekid > t.weekid and t2.passesCondition = 0
                 );

> all

select count(*)
from t
where t.weekid > all (select t2.weekid from t t2 where t2.passesCondition = 0);

我还没有意识到有这么多种表达方式。毫无疑问,还有很多。

答案 1 :(得分:1)

如果您需要考虑多个起点和终点,则可以使用类似于以下查询的计数来计算孤岛:

DECLARE @T TABLE(WeekId INT, PassedCondition BIT)
INSERT @T VALUES (1,1),(2,0),(3,0),(4,1),(5,1),(6,1),(7,1),(8,0),(9,0),(10,1)

;WITH Holes AS(SELECT WeekID FROM @T WHERE PassedCondition=0),
SegmentStart AS
(
    SELECT WeekId, HoleWeekId 
    FROM
    (
        SELECT  This.WeekId, HoleWeekId = MIN(H.WeekId)
        FROM  @T This
        INNER  JOIN Holes H ON H.WeekId > This.WeekID AND PassedCondition=1
        GROUP BY This.WeekId
        UNION 
        SELECT WeekId = MAX(WeekID), HoleWeekId=MAX(WeekID)+1 
        FROM @T 
        WHERE PassedCondition=1
    )AS X
)
SELECT 
    WeekSegmentEnd = HoleWeekId-1,
    ConsecutiveCount = COUNT(*)
FROM 
    SegmentStart
GROUP BY
    HoleWeekId       

答案 2 :(得分:0)

计算具有weekid(不包括)的 maximum passesCondition = 0 maximum weekid(不包括)之间的行):

SELECT COUNT(*)
FROM tablename t
WHERE 
  (t.weekid < (SELECT MAX(weekid) FROM tablename))
  AND
  (t.weekid > (SELECT MAX(weekid) FROM tablename WHERE passesCondition = 0)); 

如果要包括最后一个weekid,请将<更改为<=