2016-09-30 12 views
0

Mein Fall, wenn Aussage scheint falsch zu sein und ich kann nicht herausfinden, was falsch ist. Es gibt mir die gleichen Daten für die Zeit für die Erstellung und für die Aktualisierung der Zeit. hier ist, wie meine Daten aussieht:Fall Wenn Aussage mit Daten

T1:

ID  create_time 
1  08/09/2016 07:30:20AM 

T2:

ID update_time 
1  
1 08/15/2016 09:41:46AM 

Ich erwarte folgende:

ID TimeStamp 
1 08/09/2016 07:30:20AM 
1 08/15/2016 09:41:46AM 

aber mein Code gibt Werte für erstellen Zeiten für die 2 Datensätze. es sieht wie folgt aus:

ID TimeStamp 
1 08/09/2016 07:30:20AM 
1 08/09/2016 07:30:20AM 

select t1.id, t1.desc, 
Case 
WHEN t1.create_time IS NOT NULL 
THEN t1.create_time 
WHEN t2.update_time IS NOT NULL 
THEN t2.update_time 
END AS "TimeStamp" 
from t1, t2 
where t1.id=t2.id 
AND (t1.create_time BETWEEN TO_DATE ('01-AUG-2016 00:00:00', 
           'dd-mon-yyyy HH24:Mi:SS') 
       AND TO_DATE ('31-AUG-2016 23:59:59', 
          'dd-mon-yyyy HH24:Mi:SS') 
    OR ( t2.update_time 
       BETWEEN TO_DATE ('01-AUG-2016 00:00:00', 
           'dd-mon-yyyy HH24:Mi:SS') 
       AND TO_DATE ('31-AUG-2016 23:59:59', 
          'dd-mon-yyyy HH24:Mi:SS') 
      ) 
     ) 

Ich muss auch auf dem erstellen/aktualisieren Zeit als New/Update in einer separaten Spalte basierend jeden Datensatz markieren. Ich war dies mit Fall tun, wenn, wie unten:

CASE 
WHEN (t1.create_time IS NOT NULL AND t2.update_time IS NULL) 
THEN 'New' 
WHEN t2.update_time IS NOT NULL 
THEN 'Update' 
END AS "Type" 

aber dies bringt Duplikate zu sein scheint wie folgt:
ID Timestamp Typ
1 2016.08.09 New
1 2016.08.09-Update
1 2016.08.15 New
1 2016.08.15 Update-

Antwort

1

Enthält diese tun, was Sie wollen?

select t1.id, t1.desc, 
     coalesce(t2.update_time, t1.create_time) as "TimeStamp" 
from t1 left join 
    t2 
    on t1.id = t2.id and 
     t2.update_time >= date '2016-08-25' and 
     t2.update_time < date '2016-09-01' 
where (t1.create_time >= date '2016-08-25' and 
     t1.create_time < date '2016-09-01' 
    ) or 
     t2.update_time is not null; 

EDIT:

Sie scheinen eine Liste der Update zu wollen, und erstellen Sie mal für jeden Datensatz, der ein Update oder erstellen während des angegebenen Zeitraums hat. Ich denke, das wie folgt aussieht:

with ids as (
     select t1.id, t1.desc, t1.create_time 
     from t1 join 
      t2 
      on t1.id = t2.id 
     where (t1.create_time >= date '2016-08-25' and 
      t1.create_time < date '2016-09-01' 
      ) t or 
      (t2.update_time >= date '2016-08-25' and 
      t2.update_time < date '2016-09-01' 
      ) 
    ) 
select ids.* 
from ids 
union all 
select ids.id, ids.desc, t2.update_time 
from ids join 
    t2 
    on t2.id = ids.id 
where t2.update_time is not null; -- I'm not sure if the range should also be checked here. 

Hinweise:

  • Nie Kommas in der FROM Klausel. Immer verwenden explizite JOIN mit einer ON Klausel.
  • Sagen Sie einfach Nein zur archaischen Outer-Join-Syntax, die selbst Oracle ablehnt. Explizite Outer-Joins verwenden
  • Oracle unterstützt das Schlüsselwort date, sodass Sie Daten mit ISO-Standardformaten eingeben können.
+0

Sie wissen, dass es Fälle gibt, wenn alte Oracle-Syntax für Joins nicht vermieden werden kann ... zum Beispiel ein Fehler in der Implementierung von REFRESH FAST für materialisierte Ansichten schnell erfrischende verhindert, wenn die Abfrage die Ansicht erstellen enthält ANSI verbindet. Seit ich das gelernt habe, sage ich "in den meisten Fällen" statt "immer". :-) – mathguy

0

Sie machen einen äußeren Join, also erhalten Sie zwei Zeilen (alle IDs sind 1). In der zweiten ist t2.update_time NULL.

Ihre Anfrage, wie Sie es geschrieben, erste Tests für t1.create_time nicht-null zu sein. Dies gilt für BEIDE Zeilen in der äußeren Verknüpfung. So wird nur das ERSTE "WANN ... DANN" jemals bewertet.

Bitte erläutern Sie die Logik Ihrer gewünschten Ausgabe; nur zeigen, und zeigt eine Abfrage, die nicht tun, was Sie wollen, stellt keine "vollständige Spezifikation" Ihrer Anforderung.

EDIT: Das OP in einem Kommentar zu dieser Antwort angegeben, was er braucht, ist die Create_time zusammen mit allen Nicht-Null-update_time-Werte.

Dies ist einfach und erfordert keine Verbindung, es erfordert eine UNION (oder UNION ALL). In den Beispieldaten haben alle Zeilen die gleiche ID; Wenn es im wirklichen Leben mehr IDs gibt, kann man mit der WHERE-Klausel ausgewählt werden.

select id, create_time as timestamp from t1 
union all 
select id, update_time from t2 where update_time is not null; 

(Möglicherweise ORDER BY id, timestamp hinzufügen - falls erforderlich)

OP: Ist dies nicht das gewünschte Ergebnis ist, bitte erklären, wie es anders ist von dem, was man braucht.

BEARBEITEN SIE NUMMER 2: Das OP hinzugefügt, um die Anforderung - es muss auch eine Art Marker sein.

select id, create_time as timestamp , 'New' as type from t1 
union all 
select id, update_time, 'Update' from t2 where update_time is not null; 
+0

Hey - wer auch immer downvotes Antworten, ich mag Ratings oder Reputation nicht, aber zumindest zum Wohle anderer könnte man erklären, was mit der Antwort falsch ist. Sonst sind wir alle ratlos. – mathguy

+0

Ich war nicht downvote, aber ich würde vermuten, dass es ist, weil Ihre Antwort in diesem Fall ein wenig kryptisch war und Sie zum OP kommentierten. Also hat das vielleicht jemand als Kommentar nicht als Antwort verstanden? Wie auch immer, +1 für das Bemerken und Erwähnen des Hauptproblems war, dass create_time für beide Fälle nicht null ist und zuerst getestet wird, weshalb das OP wahrscheinlich dieses Ergebnis erhält. Gordon gab eine gute Antwort, vermisste jedoch ausdrücklich, die Logik der Fallreihenfolge zu erwähnen, auf die Ihre Antwort und OP ausdrücklich hinweisen. Normalerweise würde ich erwarten, dass in einer Antwort von Ihnen, obwohl – Matt

+0

@Matt klarer zu sein - mein erster Absatz sollte erklären, was in der Abfrage auf der höchsten Ebene passiert. Es gibt einen Join (ein Outer-Join, der die veraltete Oracle-Syntax verwendet), aber da dieselbe ID in beiden Tabellen vorhanden ist, ist der Join tatsächlich derselbe wie ein Inner-Join. Sie erhalten alle zwei Zeilen in der Ausgabe. Dann, im zweiten Absatz, beantwortete ich die Frage des OP, wer wollte wissen, was falsch war. In der dritten sagte ich, ich weiß nicht, was er * meinte *; Wenn er Hilfe bei der Klärung der Anfrage brauchte, musste ich wissen, was es überhaupt tun sollte. Ich hasse es, die Anforderungen zu erraten (wie Sie vielleicht wissen) – mathguy