2016-06-06 5 views
0

Ich habe Daten von mehreren Abteilungen, die ich zusammenfassen müssen, um auf einen Bericht auszugeben.Zusammenfassung Daten auch wenn Abteilung für einen Tag fehlt

In den meisten Tagen übermittelt jede Abteilung Daten. An manchen Tagen vermisst eine Abteilung möglicherweise Daten.

Ich muss einen Nullwerteintrag für diese Abteilung für den Tag reflektieren, anstatt es zu überspringen.

Ich weiß nicht warum, aber das fällt mir als eine schwierige Herausforderung auf.

Wenn meine Daten wie folgt aussieht:

Date, Department, Employee 
1 May 2016, First, Fred 
1 May 2016, First, Wilma 
1 May 2016, Second, Betty 
1 May 2016, Second, Barney 
2 May 2016, Second, Betty 
3 May 2016, First, Wilma 
3 May 2016, Second, Betty 
3 May 2016, Second, Barney 

Wenn ich einen count (*) auf diese Daten zu tun, die Ausgabe Ich hoffe, suche ist:

1 May 2016, First, 2 
1 May 2016, Second, 2 
2 May 2016, First, 0 
2 May 2016, Second, 1 
3 May 2016, First, 1 
3 May 2016, Second, 2 

Es ist die dritte Linie, "2. Mai 2016, First, 0", dass ich meine Ausgabe nicht erhalten kann.

Meine zugrunde liegenden Daten sind komplexer als oben, aber oben ist eine sinnvolle Simplex-Darstellung des Problems.

Ich bin an dem Punkt, an dem ich mit Cursors rumspiele, die versuchen, dieses Recordset zu "bauen", also denke ich, dass das ein Hinweis ist, dass ich um Hilfe bitten muss.

Antwort

1

Unter der Annahme, dass Ihre Haupttabelle ist:

create table mydata 
(ReportDate date, 
department varchar2(20), 
Employee varchar2(20)); 

wir die untenstehende Abfrage verwenden können.

with dates (reportDate) as 
(select to_date('01-05-2016','dd-mm-yyyy') + rownum -1 
    from all_objects 
    where rownum <= 
to_date('03-05-2016','dd-mm-yyyy')-to_date('01-05-2016','dd-mm-yyyy')+1), 
departments(department) as 
(select 'First' from dual 
union all 
select 'Second' from dual) , 
AllReports (reportDate, Department) as 
(select dt.reportDate, 
    dp.department 
from dates dt 
cross join 
departments dp) 
select ar.reportDate, ar.department, count(md.employee) 
from AllReports ar 
left join myData md 
on ar.ReportDate = md.reportDate and 
    ar.department = md.department 
    group by ar.reportDate, ar.department 
    order by 1, 2 

Zuerst wir Daten erzeugen, die wir interessiert sind in unserem Beispiel zwischen 01-05- 2016 und 03-05-2016. Es ist in dates WITH.

Als nächstes erstellen wir eine Liste der Abteilungen - Departments WITH.

Wir kreuzen sie, um alle möglichen Berichte zu erzeugen - AllReports WITH.

Und wir verwenden LEFT JOIN zu Ihrer Haupttabelle, um herauszufinden, welche Daten vorhanden sind und welche fehlen.

+0

Danke dcieslak - in Ihrer Version oben sieht es so aus, als ob ich die Abteilungen über die 'union all' Unterabfrage hart kodieren müsste - ist das korrekt? – MidnightThoughtful

+0

Abfrage aus Ihren Stammdaten. Verwenden Sie nicht die Abteilungen MIT, sondern Ihre reale Tabelle. Ich nehme an, Sie haben eine Tabelle DEPARTMENT, die alle möglichen Abteilungen hat. – dcieslak

+0

Haben Sie eine Datumsdimensionstabelle und eine Abteilungstabelle. CROSS JOIN-Abteilung zu Ihrem Datum Tabelle, LINKS/OUTER Join Ihre Anwesenheitstabelle auf Datum und Abteilung. Wenn Sie viele Statistiken haben, die Tag für Bericht zusammengeführt werden müssen, sollten Sie die Daten in regelmäßigen Abständen in eine Rollup-Tabelle für die Berichterstellung einstufen. – vanlee1987