我有一张看起来像这样的桌子
WeekId PassesCondition
----------------------------------
1 1
2 0
3 0
4 1
5 1
6 1
我需要编写一个查询,该查询从条件已通过的最大值WeekId
开始算起连续几周。
我已经进行了一些搜索,似乎可能需要对CTE
和ROW_NUMBER()
进行一些操作。我已经尝试了一些方法,但是结果甚至都不值得发布为“到目前为止我已经尝试过的”。
输出应该只是从条件Max(WeekId)
起经过了几周的计数。例如1、2、5等
答案 0 :(得分:2)
假设条件仅为0
或1
:
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
,请将<
更改为<=
。