Oracle - 计算满足相同给定条件的连续天数
Posted
技术标签:
【中文标题】Oracle - 计算满足相同给定条件的连续天数【英文标题】:Oracle - Count consecutive days meeting the same given criteria 【发布时间】:2015-06-09 12:08:12 【问题描述】:我的 Oracle 数据库中有以下结构:
Date Allocation id
2015-01-01 Same 200
2015-01-02 Good 200
2015-01-03 Same 200
2015-01-04 Same 200
2015-01-05 Same 200
2015-01-06 Good 200
我想要一个查询,它只需要检查前连续几天并获取分配为"Same"
的计数。
我想按日期选择,例如2015-01-05
。
示例输出:对于日期2015-01-05
,计数为3
。
新问题。通过 Lukas Eder 的查询,计数始终为 1
或 2
。但预期是3
。从 2015 年 1 月 3 日到 2015 年 1 月 5 日。
Date Allocation id
2015-01-01 Same 400
2015-01-02 Good 400
2015-01-03 Same 400
2015-01-04 Same 400
2015-01-05 Same 400
2015-01-06 Good 400
来自 Lukas Eder 的代码
SELECT c
FROM (
SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (
SELECT allocation, d,
d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
FROM t
)
)
WHERE d = DATE '2015-01-05';
【问题讨论】:
Get count of consecutive days meeting a given criteria 的可能重复项 我意识到这篇文章包含一个新问题,但实际上是同一个问题。 “新问题”是旧答案不充分;核心问题是一样的。 【参考方案1】:试一试:
create table mbtmp(d_date date, alloc varchar2(20), id number);
insert into mbtmp values (to_date('2015-01-01','yyyy-mm-dd'),'SAME',200);
insert into mbtmp values (to_date('2015-01-02','yyyy-mm-dd'),'GOOD',200);
insert into mbtmp values (to_date('2015-01-03','yyyy-mm-dd'),'SAME',200);
insert into mbtmp values (to_date('2015-01-04','yyyy-mm-dd'),'SAME',200);
insert into mbtmp values (to_date('2015-01-05','yyyy-mm-dd'),'SAME',200);
insert into mbtmp values (to_date('2015-01-06','yyyy-mm-dd'),'GOOD',200);
COMMIT;
SELECT max(length(sames) - length(replace(sames,'|',null)) - 1) from (
select regexp_substr( pth,'[|SAME]+') sames
FROM(
SELECT sys_connect_by_path(alloc,'|') pth
from mbtmp m
WHERE d_Date > ( select max(d_date) from mbtmp
where d_Date < to_date('2015-01-05','yyyy-mm-dd')
And alloc != 'SAME' )
START WITH d_Date = to_date('2015-01-05','yyyy-mm-dd')
CONNECT BY Prior d_date = d_date + 1));
现在,如果不是连续天规则,即 - 如果即使天数列表中存在间隙,您仍然计算在内,那么您可以使用更简单的查询:
select count(d_Date)
FROM mbtmp
WHERE d_Date > ( select max(d_date) from mbtmp
where d_Date < to_date('2015-01-05','yyyy-mm-dd')
And alloc != 'SAME' )
and d_date <= to_date('2015-01-05','yyyy-mm-dd')
【讨论】:
【参考方案2】:您可以使用不同的行来识别组。这就是您的查询正在做的事情。如果您想要特定日期的值,请使用:
select t.*
from (select t.*,
(row_number() over (order by date) -
row_number() over (partition by allocation order by date)
) as grp
from table t
) t
where d = date '2015-01-05';
关于为什么您的问题中的版本不起作用,我最好的猜测是因为您的 date
可能有时间组件。我假设d
是date
列。
编辑:
要获取计数,请使用子查询和count(*)
作为分析函数:
select t.*
from (select t.*, count(*) over (partition by grp, allocation) as cnt
from (select t.*,
(row_number() over (order by date) -
row_number() over (partition by allocation order by date)
) as grp
from table t
) t
) t
where d = date '2015-01-05';
或者,如果你只想要计数,你可以使用聚合:
select date, count(*) as cnt
from (select t.*,
(row_number() over (order by date) -
row_number() over (partition by allocation order by date)
) as grp
from table t
) t
group by date, allocation
having date = date '2015-01-05';
【讨论】:
谢谢。这并没有给我连续几天使用的“相同”计数。以上是关于Oracle - 计算满足相同给定条件的连续天数的主要内容,如果未能解决你的问题,请参考以下文章