获得满足给定标准的连续天数

时间:2015-06-09 07:35:37

标签: 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

我希望有一个查询只需检查前几天的连续日,并获得分配为"Same"的计数。

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

新问题。根据Lukas Eder的查询,计数始终为12。但预期的是3。为什么?!

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

预期输出是这样的,First_day结束最后一天没必要:

id   count    first_day   Last_Day
200  3        2015-01-03  2015-01-05
400  3        2015-01-03  2015-01-05

4 个答案:

答案 0 :(得分:3)

此查询将产生每行的计数:

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
)
ORDER BY d;

然后,您可以对其进行过滤以查找给定行的计数:

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

说明:

派生表用于计算不同的"分区"每个日期和分配part

  SELECT allocation, d,
         d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
  FROM t

结果是:

allocation  d           part
--------------------------------
Same        01.01.15    31.12.14
Good        02.01.15    01.01.15
Same        03.01.15    01.01.15
Same        04.01.15    01.01.15
Same        05.01.15    01.01.15
Good        06.01.15    04.01.15

part生成的具体日期无关紧要。它只是某个日期,对于每个"组来说都是相同的#34;分配中的日期。然后,您可以使用(allocation, part)窗口函数计算count(*) over(...)的相同值的数量:

SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (...)
ORDER BY d;

产生你想要的结果。

数据

我已使用下表作为示例:

CREATE TABLE t AS (
  SELECT DATE '2015-01-01' AS d, 'Same' AS allocation FROM dual UNION ALL
  SELECT DATE '2015-01-02' AS d, 'Good' AS allocation FROM dual UNION ALL
  SELECT DATE '2015-01-03' AS d, 'Same' AS allocation FROM dual UNION ALL
  SELECT DATE '2015-01-04' AS d, 'Same' AS allocation FROM dual UNION ALL  
  SELECT DATE '2015-01-05' AS d, 'Same' AS allocation FROM dual UNION ALL
  SELECT DATE '2015-01-06' AS d, 'Good' AS allocation FROM dual
);

答案 1 :(得分:1)

考虑以下问题来解决您的问题:

SELECT COUNT(*) AS `count` FROM test t
WHERE `date` < '2015-01-05' AND allocation = 'Same';

我们假设给定的日期是'2015-01-05'。这里的想法是选择所有小于'2015-01-05'的日期,这意味着它的前几天。由于分配必须为“相同”,因此它也包含在声明的条件部分中。

答案 2 :(得分:0)

试试这个:

SELECT  count(Allocation) as total_allocation FROM table_name 
WHERE (Date BETWEEN CURDATE() - INTERVAL 1 DAY AND CURDATE()) 
AND (Allocation='Same');

这将从今天的日期之前的日期获取所有记录,其Allocation ='Same'

答案 3 :(得分:0)

更容易:

DEMO

SELECT count(*) AS c
FROM t
WHERE d <
TO_DATE (
       '2015-01-05'
        ,'yyyy-mm-dd'
)
AND allocation = 'Same';