Нужен запрос, чтобы вернуть ноль, когда count(*) не соответствует ни одной записи

SELECT COUNT(*),TRUNC(TEST_DATE_CREATE) 
FROM TEST_TABLE 
WHERE TEST_DATE_CREATE > (SYSDATE - 10)
GROUP BY TRUNC(TEST_DATE_CREATE);

Мне нужно, чтобы приведенный выше запрос возвращал счет 0 в случае отсутствия записей для определенной даты. Кажется, этого не происходит.

Пробовал NVL, декодировать. Обнаружено, что проблема связана с предложением group by, но не знаю, как это исправить.

Пожалуйста помоги !!


person Chittprakash    schedule 10.06.2013    source источник
comment
Что вы пытаетесь достичь? Ваш заголовок предполагает, что вы хотите, чтобы count(*) возвращал NULL, в то время как в описании проблемы вы упоминаете, что хотите вернуть 0 в случае отсутствия строк.   -  person diederikh    schedule 10.06.2013
comment
Или stackoverflow.com/questions/12343244/   -  person Ben    schedule 10.06.2013


Ответы (2)


Вам нужно создать список интересующих вас дат, а затем выполнить левое внешнее соединение с вашей таблицей, чтобы найти записи, соответствующие каждой дате. Что-то вроде этого:

with tmp_dates as (
    select trunc(sysdate) - level + 1 as tmp_date
    from dual
    connect by level <= 10
)
select count(tt.test_date_create), td.tmp_date
from tmp_dates td
left join test_table tt on trunc(tt.test_date_create) = td.tmp_date
group by td.tmp_date
order by tmp_date;

Общее табличное выражение само по себе генерирует список дат:

select trunc(sysdate) - level + 1 as tmp_date
from dual
connect by level <= 10;

TMP_DATE
---------
10-JUN-13 
09-JUN-13 
08-JUN-13 
07-JUN-13 
06-JUN-13 
05-JUN-13 
04-JUN-13 
03-JUN-13 
02-JUN-13 
01-JUN-13 

Вы можете настроить предел level и то, как он добавляется к sysdate, чтобы изменить диапазон, например. оглянуться назад или исключить сегодняшний день.

Затем основной выбор использует это для поиска совпадающих записей. Поскольку это внешнее соединение, в нем перечислены все сгенерированные даты и нулевой счет там, где нет совпадений.

скрипт SQL.

person Alex Poole    schedule 10.06.2013

Трудно понять, чего ты хочешь, но

select decode(count(*), 0, null, count(*)) 

вернет null, если в группе нет записей.

ОБНОВЛЕНИЕ: Теперь стало ясно, чего вы хотите:

select date_code, cnt
from(
    select trunc(sysdate-10) + level - 1 as date_code
    from dual
    connect by level <= 10
    )
left join(
    SELECT COUNT(*) cnt,TRUNC(TEST_DATE_CREATE)  trunc_create
    FROM TEST_TABLE 
    WHERE TEST_DATE_CREATE > (SYSDATE - 10)
    GROUP BY TRUNC(TEST_DATE_CREATE);
) on trunc_create = date_code

ОБНОВЛЕНИЕ2: теперь стало понятнее, что вы хотите, нули, а не нули:

select date_code, count(*) 
from(
    select trunc(sysdate-10) + level - 1 as date_code
    from dual
    connect by level <= 10
    )
left join TEST_TABLE on TRUNC(TEST_DATE_CREATE) = date_code
GROUP BY date_code;
person Florin Ghita    schedule 10.06.2013
comment
извините за путаницу. вышеприведенный запрос теперь действительно повторяет строки. поскольку нет данных для TEST_DATE_CREATE › (SYSDATE - 10) - person Chittprakash; 10.06.2013
comment
что мне нужно, так это запрос на перенастройку 0, например 0 1 июня 2013 г. 0 2 июня 2013 г. 0 3 июня 2013 г. - person Chittprakash; 10.06.2013