2014-08-28 136 views
1

假設我有一個日期表。按日期總結計數

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特有溶液是可接受的。

回答

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 
+0

輝煌,非常感謝! – 2014-08-28 05:47:44

1

由ajmalmhd04的精心佈置的回答一些輕微的變化。

這裏我們以TRUNC(anydate,'MONTH')的形式使用TRUNC(),它返回相關月份的第1天,它保留的數據類型比在大型數據集中處理字符串更快。

此外還使用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查看。