2016-04-21 3 views
0
 
table A 
no date  count 
1 20160401 1 
1 20160403 4 
2 20160407 3 
 
result 
no date  count 
1 20160401 1 
1 20160402 0 
1 20160403 4 
1 20160404 0 
. 
. 
. 
2 20160405 0 
2 20160406 0 
2 20160407 3 
. 
. 
. 

Ich bin mit Oracle in fehlt und ich möchte eine Abfrage schreiben, die Zeilen für jedes Datum innerhalb eines Bereichs zurückgibt, basierend auf Tabelle A.geben Sie bitte Ihre Reisedaten ein Datumsbereich aus einer Tabelle

Ist Gibt es eine Funktion in Oracle, die mir helfen kann?

+0

Es gibt eine gute Chance gibt es bereits eine Antwort auf Stack-Überlauf. Sicherlich muss es eine Möglichkeit geben, sich zwischen date * x * und * y * zu einer Kalender-Tabelle zu verbinden und Ihre Ergebnisse damit zu verbinden? Ich konnte es jedoch nicht finden. Hoffentlich kann jemand, der mehr Wissen im Oracle-Tag haben kann! :) –

+0

Nur um zu klären. Das sind Tabellen und nicht das Ergebnis einer Group-by/Aggregate-Abfrage? –

+0

Was ist Ihre Anforderung? + Was hast du probiert? Haben Sie tatsächlich eine Anfrage geschrieben oder versucht, das gewünschte Ergebnis zu erzielen? Wenn ja, bitte teilen Sie das. Wenn möglich, erläutern Sie bitte auch die Logik, die erforderlich ist, um die Datenausgabe in einfacher Sprache zu strukturieren (+ technische Jargons, wenn Sie möchten). – Annjawn

Antwort

0

Try this:

with 
    A as (
    select 1 no, to_date('20160401', 'yyyymmdd') dat, 1 cnt from dual union all 
    select 1 no, to_date('20160403', 'yyyymmdd') dat, 4 cnt from dual union all 
    select 2 no, to_date('20160407', 'yyyymmdd') dat, 3 cnt from dual), 
    B as (select min(dat) mindat, max(dat) maxdat from A t), 
    C as (select level + mindat - 1 dat from B connect by level + mindat - 1 <= maxdat), 
    D as (select distinct no from A), 
    E as (select * from D,C) 
select E.no, E.dat, nvl(cnt, 0) cnt 
from E 
full outer join A on A.no = E.no and A.dat = E.dat 
order by 1, 2, 3 
0

Dies ist keine Oracle-spezifische Antwort, Sie müssen es in Orakel selbst übersetzen.

Eine Intervalle Tabelle, alle ganzen Zahlen von 0 bis 999. So etwas wie diese enthält:

CREATE TABLE intervals (days int); 
INSERT INTO intervals (days) VALUES (0), (1); 
DECLARE @rc int; 
SELECT @rc = 2; 
WHILE (SELECT Count(*) FROM intervals) < 1000 BEGIN 
    INSERT INTO intervals (days) SELECT days + @rc FROM intervals WHERE days + @rc < 1000; 
    SELECT @rc = @rc * 2 
END; 

Dann werden alle Termine im Bereich kann durch Zugabe von intervals.days zu dem ersten Tag identifiziert werden, Sie haben bekommen, wo das erste Datum + intervals.days < = das Enddatum ist, und das resultierende Datum ist neu. Führen Sie dies durch, indem Sie Intervalle mit Ihrem eigenen Tisch verbinden. So etwas wie (es wäre in SQL sein, aber auch hier werden Sie übersetzen müssen):

SELECT DateAdd(a.date, d, i.days) 
FROM (select min(date) from table_A) a, intervals I 
WHERE DateAdd(a.date, d, i.days) < (select max(date) from table_A) 
    AND NOT EXISTS (select 1 from table_A aa where aa.date = DateAdd(a.date, d, i.days)) 

Hoffnung, das gibt Ihnen einen Ausgangspunkt

1

Sie die SEQUENCES verwenden können.

Zuerst eine Sequenz erstellen

Create Sequence seq_name start with 20160401 max n; 

wobei n der Maximalwert ist bis u angezeigt werden soll.

Verwenden Sie dann die SQL-

select seq_name.next,case when seq_name.next = date then count else 0 end from tableA; 

Hinweis: - Es ist besser, nicht Datum zu verwenden, da die Spaltennamen zählen.

Verwandte Themen