这类事情有很多众所周知的 SQL 技巧。我喜欢使用MATCH_RECOGNIZE 功能。我发现它比其他方式更神秘。试试这个:
with input ( d, v ) as
(
SELECT to_date('15-Jan-2020','DD-MON-YYYY'),'true' FROM DUAL UNION ALL
SELECT to_date('14-Jan-2020','DD-MON-YYYY'),'true' FROM DUAL UNION ALL
SELECT to_date('13-Jan-2020','DD-MON-YYYY'),'true' FROM DUAL UNION ALL
SELECT to_date('12-Jan-2020','DD-MON-YYYY'),'false' FROM DUAL UNION ALL
SELECT to_date('11-Jan-2020','DD-MON-YYYY'),'true' FROM DUAL UNION ALL
SELECT to_date('10-Jan-2020','DD-MON-YYYY'),'false' FROM DUAL UNION ALL
SELECT to_date('09-Jan-2020','DD-MON-YYYY'),'false ' FROM DUAL)
select d, v, cnt
from input
match_recognize (
order by d
measures running count(value_true.d) as cnt
all rows per match
pattern (value_true*)
define
value_true AS value_true.v = 'true'
)
order by d desc
;
+----------------------+--------+-----+
| D | V | CNT |
+----------------------+--------+-----+
| 15-JAN-2020 00:00:00 | true | 3 |
| 14-JAN-2020 00:00:00 | true | 2 |
| 13-JAN-2020 00:00:00 | true | 1 |
| 12-JAN-2020 00:00:00 | false | 0 |
| 11-JAN-2020 00:00:00 | true | 1 |
| 10-JAN-2020 00:00:00 | false | 0 |
| 09-JAN-2020 00:00:00 | false | 0 |
+----------------------+--------+-----+
MATCH_RECOGNIZE 在行中查找模式。在这种情况下,我们给出如下模式:
pattern (value_true*)
找到零个或多个(即星号)“value_true”行。根据我们的定义,一行是“value_true”:
define
value_true AS value_true.v = 'true'
然后我们告诉 Oracle,计算与模式匹配的行数 COUNT(),并将结果称为 cnt。因为,在我们的MATCH_RECOGNIZE 中,是按日期按升序 顺序排序的,并且由于我们的MEASURES 子句指定了RUNNING COUNT(而不是FINAL COUNT),所以这是一个“真" 从组的开头到当前行(包括当前行)的行。也就是说,连续的先前“真实”行数(如果计算当前行)。
也许“不那么神秘”不是正确的表达方式。我的意思是,也许,“更明确”。语法不太熟悉,但它说明了你在做什么:即寻找value = true 的连续行的模式并计算它们。