Ich erstelle eine sehr komplexe SQL-Abfrage in Oracle mit mehreren CTEs, wobei letztere Ausdrücke auf Werten von früheren basieren. Ich finde jedoch, dass die gesamte Ausführung anhält, wenn einer der vorherigen CTEs keine Daten enthält. Zum Beispiel:Oracle SQL CTE (allgemeiner Tabellenausdruck) wo keine Daten
WITH CTE1 AS
(
SELECT
PEOPLE.ID AS PID,
APPLICATIONS.DATE AS APPDATE
FROM
PEOPLE,
APPLICATIONS
WHERE
APPLICATIONS.PERSON_ID = PEOPLE.ID
AND APPLICATIONS.DATE BETWEEN TO_DATE('2015-01-01','YYYY-MM-DD') AND TO_DATE('2015-01-31','YYYY-MM-DD')
),
CTE2 AS
(
SELECT
APPLICATIONS.PERSON_ID AS PID
MIN(APPLICATIONS.DATE) AS EARLIEST_APPDATE
FROM
CTE1,
APPLICATIONS
WHERE
APPLICATIONS.PERSON_ID = CTE1.PID
AND APPLICATIONS.DATE < ADD_MONTHS(CTE1.APPDATE, -18)
GROUP BY APPLICATIONS.PERSON_ID
),
MAIN_QUERY AS
(
SELECT
CTE1.PID AS PID
FROM
CTE1, CTE2
WHERE
-- Note that the PIDs should either match, or should not exist in CTE2
CTE1.PID = CTE2.PID OR (NOT EXISTS (SELECT PID FROM CTE2 WHERE CTE1.PID = CTE2.PID))
)
SELECT
MAIN_QUERY.PID
FROM MAIN_QUERY
Natürlich weiß ich, dass das obige Beispiel in sich völlig sinnlos ist, aber ich habe das nur vereinfacht das Problem zu veranschaulichen. CTE2 gibt das früheste Datum einer Anwendung zurück, die von derselben Personenkennung erstellt wurde, bei der die Anmeldung mehr als 18 Monate vor dem Anmeldetag von CTE1 liegt. Wie auch immer ... was ist, wenn es solche Anwendungen nicht gibt? CTE2 kann null Zeilen zurückgeben.
Sie werden feststellen, dass CTE2 nicht selbst in der endgültigen Abfrage referenziert wird. Ein leerer CTE2 wird in MAIN_QUERY behandelt. In Bezug auf die letzte Abfrage sollte es also keine Rolle spielen, ob CTE2 tatsächlich irgendwelche Zeilen zurückgibt oder nicht.
Allerdings die Anwendung, die ich verwende (Business Objects) wirft einen Fehler, dass die Abfrage hat "keine Daten zu holen", wenn CTE2 keine Zeilen hat.
Ich möchte einen Weg um diese zu finden, um meine Abfrage zu ermöglichen, selbst wenn CTE2 null zurückgibt. Vielen Dank.
Unrelated, aber: Sie sollten einen expliziten 'JOIN' Operator anstelle des alten veralteten implizite schließt sich in dem' where' Klausel beginnen. –
Ich bin mir nicht sicher, ich verstehe ganz, was Sie wollen, aber ich denke, eine einfache Outer Join 'main_query' würde tun: 'von cte1 links Join cte2 auf cte1.pid = cte2.pid' –
Danke - aber wie gesagt, die echte Abfrage ist sehr viel komplexer als das Beispiel, und ich bin nicht sicher, wie Joins funktionieren würde: Ich habe mindestens * drei * vorbereitende CTEs, die vor der Hauptabfrage ausgeführt werden müssen, und in jedem CTE gibt es eine Last von komplex Zeug geht weiter. Ich habe keine Ahnung, wie ich mit Joins fortfahren würde. Ich verstehe CTEs, also arbeite ich damit. Dankbar, wenn jemand helfen kann - danke. –