Как вернуть нули по месяцам, которых нет в базе данных
Я пытаюсь вернуть количество людей, зарегистрированных в конкретном месяце, но хотел бы также вернуть нули в месяцах, которых нет в базе данных.
Следующий запрос возвращает количество людей, зарегистрированных в месяцах в базе данных:
select
extract(year from "DATECREATED") as YEAR,
extract(month from "DATECREATED") as mon,
count("USERID") as Total
from
TBLG2O_USEROFO
where
extract(year from "DATECREATED") = '2014'
group by
extract(year from "DATECREATED"),
extract(month from "DATECREATED")
order by
1, 2
3 ответа
К сожалению, для этого вам нужна вторая таблица, которая просто содержит номер месяца в строке.
Предполагая, что вы создаете таблицу с именем MONTHS
с одним столбцом, MONTH_NUMBER
Вы можете использовать этот запрос для создания искомого результата - он будет подсчитывать количество строк в месяц для указанного года и показывать нули для любого месяца без строк.
Обратите внимание, что этот запрос также имеет недостаток - он будет работать только в течение календарного года, поэтому вы не сможете разбить его по годам (скажем, июль 2013 - июнь 2014).
SELECT COALESCE(YEAR, 2014) AS YEAR,
MONTHS.MONTH_NUMBER AS MONTH,
COALESCE(TOTAL, 0) AS "MONTH COUNT"
FROM (SELECT EXTRACT(YEAR FROM DATECREATED) AS YEAR,
EXTRACT(MONTH FROM DATECREATED) AS MONTH,
COUNT(DATECREATED) AS TOTAL
FROM TBLG2O_USEROFO
WHERE EXTRACT(YEAR FROM DATECREATED) = '2014'
GROUP BY EXTRACT(YEAR FROM DATECREATED),
EXTRACT(MONTH FROM DATECREATED)) LFT
RIGHT OUTER JOIN MONTHS
ON MONTH_NUMBER = LFT.MONTH
ORDER BY YEAR, MONTH
Смотрите этот запрос в действии на SQL Fiddle.
По сути, это Oracle-версия ответа @Eran's MySQL.
Я проверил это на mysql, поэтому вам может потребоваться немного поработать над оракулом.
Сначала создайте таблицу с месяцами года...
create table months(month int);
insert into months values(1);
insert into months values(2);
insert into months values(3);
insert into months values(4);
insert into months values(5);
insert into months values(6);
insert into months values(7);
insert into months values(8);
insert into months values(9);
insert into months values(10);
insert into months values(11);
insert into months values(12);
Используйте правильное соединение с таблицей месяцев, чтобы достичь желаемого эффекта:
select coalesce(YEAR, 2014) year, m.month, coalesce(Total, 0) as total
from
(select year(DATECREATED) as YEAR, month(c. DATECREATED) month, count("DATECREATED") as Total
from comments c
where year(DATECREATED) ='2014'
group by year, month(c.date_sent)) as c
right join months m
on c.month = m.month
order by year, month
Если вы не можете добавить временную таблицу, вот способ обойти это:
select coalesce(YEAR, 2014) year, m.month, coalesce(Total, 0) as total
from
(select year(DATECREATED) as YEAR, month(c. DATECREATED) month, count("DATECREATED") as Total
from comments c
where year(DATECREATED) ='2014'
group by year, month(c.date_sent)) as c
right join
(select 1 as month union select 2 as month union select 3 as month
union select 4 as month union select 5 as month union select 6 as month
union select 7 as month union select 8 as month union select 9 as month
union select 10 as month union select 11 as month union select 12 as month) m
on c.month = m.month
order by year, month
В Oracle, когда вам нужно "синтезировать" строки, которые непосредственно не присутствуют в базе данных, вы можете использовать предложение моделирования. ключевое слово модели
Я использовал SQL Fiddle Джареда для создания еще более простого примера, без какой-либо второй таблицы:
select * from
(
select count(1) cnt, trunc(datecreated, 'MONTH') dt
from TBLG2O_USEROFO
group by trunc(datecreated, 'MONTH')
)
model
--partition by (department)
dimension by (dt)
measures (cnt, cast (null as number) tech_cnt)
rules sequential order(
tech_cnt[ for dt from to_date('2013-01-01','RRRR-MM-DD')
to to_date('2014-12-31','RRRR-MM-DD')
increment NUMTOYMINTERVAL(1,'MONTH')]
= nvl(cnt[cv(dt)], 0)
)
order by dt;
Представьте, что результатом запроса является лист Excel. Тогда назначение tech_cnt[dt] = nvl(cnt[cv(dt), 0)
является "макросом Excel".