Некоторые незначительные вариации на хорошо продуман ответ по ajmalmhd04.
Здесь мы используем TRUNC() в виде TRUNC (anydate, 'MONTH), который возвращает 1-й день соответствующего месяца и сохраняет тип данных, который может быть быстрее, чем работа со строками в больших наборах данных.
Дополнительно используется синтаксис ANSI join.
-- 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.
блестящий, большое спасибо! –