2013-10-11 3 views
1

я пытаюсь получить некоторые данные отчетаВыберите запрос для возврата значений для всех записей

Это мой запрос:

SELECT sourceCode as "Source", to_char(myTimestamp, 'YYYY-MM-DD') as "Date", statusCode as "Status", count(*) as "Count" 
FROM archive_table 
WHERE myTimestamp BETWEEN TO_TIMESTAMP('2013-09-30','yyyy-mm-dd') AND TO_TIMESTAMP('2013-10-05','yyyy-mm-dd') 
GROUP BY sourceCode, to_char(myTimestamp, 'YYYY-MM-DD'), statusCode 
ORDER BY 1, 2, 3 

Это выход:

Source Date Status Count 
Source1 9/30/2013 C 10 
Source1 10/1/2013 C 8 
Source1 10/2/2013 C 24 
Source1 10/2/2013 O 4 
Source2 10/4/2013 C 22 
Source2 10/4/2013 O 7 
Source3 10/1/2013 C 2 
Source4 9/30/2013 C 15 
Source4 9/30/2013 O 15 
Source4 10/1/2013 C 24 
Source4 10/1/2013 O 12 

Что бы например, для просмотра всех графов 0, например Source1 с датой 9/30/2013 не имеет статуса 0 в базе данных, поэтому я хотел бы, чтобы он отображал:

Source1 9/30/2013 O 0 

Другой пример, есть теперь Source2 вообще для 9/30/2013 поэтому он должен показывать:

Source2 9/30/2013 O 0 
Source2 9/30/2013 C 0 

Im надеясь, что это простой способ сделать это. Для получения дополнительной информации есть только 4 «источника», а статус - «O» или «C», очевидно, что диапазон дат указан в предложении where.

ответ

2

SQL Fiddle for easy reference

Самый простой способ сделать это, если у вас есть таблица значений, содержащих возможные источники, Статусы, и даты. Даже если вы этого не сделаете, вы все равно можете генерировать производные таблицы «на лету», которые могут поддерживать ваш запрос.

Это генерирует каждую комбинацию источника, состояния и даты, которые вы пытаетесь выполнить.

select 
    * 
from 
    (select 'Source1' Source from Dual 
    union select 'Source2' from Dual 
    union select 'Source3' from Dual 
    union select 'Source4' from Dual 
    ) s 
    cross join (
    select 'O' Status from Dual 
    union select 'C' from Dual 
    ) c 
    cross join (
    select '2013-09-30' Dt from Dual 
    union select '2013-10-01' from Dual 
    union select '2013-10-02' from Dual 
    union select '2013-10-03' from Dual 
    union select '2013-10-04' from Dual 
    union select '2013-10-05' from Dual 
    ) d; 

Тогда вы можете взять все это и осталось присоединиться к вашему archive_table и сделать свою группировку на сфабрикованных данных, а не базовой таблицы и сделать подсчет на одном из ваших archive_table колонн.

select 
    s.Source, 
    c.Status, 
    d.Dt, 
    count(t.Source) 
from 
    (select 'Source1' Source from Dual 
    union select 'Source2' from Dual 
    union select 'Source3' from Dual 
    union select 'Source4' from Dual 
    ) s 
    cross join (
    select 'O' Status from Dual 
    union select 'C' from Dual 
    ) c 
    cross join (
    select '2013-09-30' Dt from Dual 
    union select '2013-10-01' from Dual 
    union select '2013-10-02' from Dual 
    union select '2013-10-03' from Dual 
    union select '2013-10-04' from Dual 
    union select '2013-10-05' from Dual 
    ) d 
    left join test t 
    on s.Source = t.Source 
     and c.Status = t.Status 
     and d.Dt = t.Dt 
group by 
    s.Source, 
    c.Status, 
    d.Dt 
+0

Там может быть более простой способ сделать это, но я не очень хорошо разбираюсь в нюансах Oracle, поскольку работаю в основном с SQL Server. По крайней мере, это работает, и, возможно, кто-то придет с более элегантным ответом. –

+0

Derek Есть ли способ, чтобы присоединиться к вашим крест-соединениям к другому запросу? Что-то вроде (результаты ваших левых объединений перекрестного соединения) как x left join (результаты моего собственного запроса) y на x.source = y.source ... и т. Д. Я играл с ним вчера вечером, я продолжал получать ошибки - я думаю, я знаю только, как присоединиться к существующей таблице – Kairan

+0

Мой запрос делает именно это. См. Последнее соединение, где он выполняет левое соединение, чтобы «проверить» –

1

Вместо указания каждой даты в диапазоне дат, используйте следующую команду и вам нужно только включать начальную и конечную даты:

SELECT 
    TO_DATE('09/30/2013','mm/dd/yyyy') - 1 + LEVEL dt 
FROM dual 
    CONNECT BY 
LEVEL <= (TO_DATE('10/05/2013','mm/dd/yyyy') 
     - TO_DATE('09/30/2013','mm/dd/yyyy')) + 1 
Смежные вопросы