Sql Oracle-计算满足相同给定条件的连续天数

Sql Oracle-计算满足相同给定条件的连续天数,sql,oracle,Sql,Oracle,我的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 我想有一个查询,必须只检查前连续几天,并获

我的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
我想有一个查询,必须只检查前连续几天,并获得分配相同的计数

我想按日期选择,例如2015-01-05。 输出示例:对于日期2015-01-05,计数为3

新问题。对于Lukas Eder的查询,计数始终为1或2。但预期的结果是3。从2015-01-03到2015-01-05

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';

您可以使用不同的行来标识组。这就是您的查询所做的。如果希望在特定日期获得该值,请使用:

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';
我对你问题中的版本不起作用的最佳猜测是因为你的约会可能有时间成分。我假设d是日期列

编辑:

要获取计数,请使用子查询和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';

您可以使用不同的行来标识组。这就是您的查询所做的。如果希望在特定日期获得该值,请使用:

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';
我对你问题中的版本不起作用的最佳猜测是因为你的约会可能有时间成分。我假设d是日期列

编辑:

要获取计数,请使用子查询和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';
试一试:

    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') 
试一试:

    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') 

谢谢。这不会给我连续几天使用的相同的计数。Thx。这不会给我连续几天使用的相同的计数。Thx。这并没有给我连续几天使用的相同的计数。可能的重复我意识到这篇文章包含了一个新问题,但实际上是同一个问题。新的问题是旧的答案不够充分;核心问题是一样的。我意识到这篇文章可能重复了一个新的问题,但实际上是同一个问题。新的问题是旧的答案不够充分;核心问题是一样的。我意识到这篇文章可能重复了一个新的问题,但实际上是同一个问题。新的问题是旧的答案不够充分;核心问题也是如此。