按日期汇总计数

时间:2014-08-28 05:13:07

标签: sql oracle

假设我有一张约会表。

select * from t;
d
-
2014/01/02
2014/02/05
2014/02/12
2014/04/01

什么查询将按月提供总行数?

 2014/01  1
 2014/02  2
 2014/04  1

同样,累计总数

2014/01  1
2014/02  3
2014/04  4

最后,没有行的月份为零值

2014/01  1
2014/02  2
2014/03  0
2014/04  1

特定于Oracle的解决方案是可以接受的。

2 个答案:

答案 0 :(得分:3)

假设表名为t 以下记录:

2014/01/02
2014/02/05
2014/02/12
2014/04/01

1)

SELECT *
FROM
     (SELECT TO_CHAR(my_date,'yyyy/mm')my_date, COUNT(*)
     FROM t
     GROUP BY TO_CHAR(my_date,'yyyy/mm')
     )
ORDER BY to_date(my_date,'yyyy/mm');

结果:

2014/01 1
2014/02 2
2014/04 1

以下查询: 2)

SELECT my_date, sum(my_count) over ( order by 1 rows unbounded preceding) cumulative
FROM
     (SELECT TO_CHAR(my_date,'yyyy/mm')my_date,
          COUNT(*) my_count
     FROM t
     GROUP BY TO_CHAR(my_date,'yyyy/mm')
     )
ORDER BY to_date(my_date,'yyyy/mm');

结果累积计数:

2014/01 1
2014/02 3
2014/04 4

3)整年:

SELECT b.all_date,nvl(my_count,0)my_count
FROM
     (SELECT TO_CHAR(my_date,'yyyy/mm')my_date,
          COUNT(*) my_count
     FROM t
     GROUP BY TO_CHAR(my_date,'yyyy/mm')
     )A,
     (SELECT TO_CHAR(add_months(to_date('2014/01/01','yyyy/mm/dd')-1 ,LEVEL),'yyyy/mm') all_date
     FROM dual
     CONNECT BY level <= 12
) b
WHERE A.mY_date(+) = b.all_date
ORDER BY to_date(b.all_date,'yyyy/mm');

结果:

2014/01 1
2014/02 2
2014/03 0
2014/04 1
2014/05 0
2014/06 0
2014/07 0
2014/08 0
2014/09 0
2014/10 0
2014/11 0
2014/12 0

答案 1 :(得分:1)

ajmalmhd04给出了很好的答案。

这里我们以TRUNC(anydate,&#39; MONTH&#39;)的形式使用TRUNC()返回相关月份的第一天,它保留的数据类型比使用字符串更快大数据集。

另外使用ANSI连接语法。

-- full monthly range over 12 months
-- example, 12 months starting at Jan 1 current year
SELECT ADD_MONTHS(TRUNC(sysdate,'YEAR'),LEVEL) range_month
FROM dual
CONNECT BY level <= 12

- 收集基础数据

SELECT TO_CHAR(the_month,'yyyy-mm-dd') AS the_month, the_count
FROM (
     SELECT TRUNC(my_date,'MONTH') AS the_month, COUNT(*) AS the_count
     FROM t
     GROUP BY TRUNC(my_date,'MONTH')
     )
ORDER BY the_month
;

- 产生累积

SELECT
       TO_CHAR(the_month,'yyyy-mm-dd') AS the_month
     , the_count
     , sum(the_count) over(order by the_month rows unbounded preceding) AS cumulative
FROM (
     SELECT TRUNC(my_date,'MONTH') AS the_month, COUNT(*) AS the_count
     FROM t
     GROUP BY TRUNC(my_date,'MONTH')
     )
ORDER BY the_month
;

- 将范围与基础数据和由左外连接累积

SELECT
       TO_CHAR(Y.range_month,'yyyy-mm-dd') AS the_month
     , NVL(T.the_count,0)                  AS the_count
     , sum(T.the_count) over(order by Y.range_month rows unbounded preceding) AS cumulative
FROM
     (
      SELECT ADD_MONTHS(TO_DATE('2014-01-01','yyyy-mm-dd'),LEVEL) range_month /* fixed date used for example only */
      FROM dual
      CONNECT BY level <= 12
     ) Y
LEFT OUTER JOIN (
                 SELECT TRUNC(my_date,'MONTH') AS the_month, COUNT(*) AS the_count
                 FROM t
                 GROUP BY TRUNC(my_date,'MONTH')
                ) T
                  ON Y.range_month = T.the_month
ORDER BY 
       Y.range_month
;  

以上内容可在this SQLfiddle demo查看。