Ihr erster äußerer Join , wie erwartet, erzeugt:
| REASON | MONTH | ------------------- | A | May | | A | May | | A | July | | A | June | | B | May | | B | June | | D | (null) |
Da Outer Joins jedoch Ergebnisse liefern, wenn die Join-Bedingung mindestens einmal erfüllt ist (und nur NULL
einführen Aufzeichnungen, wenn die Bedingung nie ist zufrieden), Ihr zweiter äußerer Join
dann nicht Produziere einen Datensatz für (B, July)
; es löscht auch Reason = 'D'
vollständig, weil die Join-Bedingung nicht erfüllt ist (und alle drei Monate an anderer Stelle erfüllt wurden):
| REASON | MONTH | ------------------ | A | May | | A | May | | B | May | | A | June | | B | June | | A | July |
Während Sie könnten den Verlust von Reason = 'D'
beheben durch Hinzufügen
OR a.Month IS NULL
Ihrer Join-Bedingung entsprechen, werden Sie (B, July)
immer noch nicht produzieren . Stattdessen, weil Sie jedes Paar (Reason, Month)
erhalten möchten , müssen Sie CROSS JOIN
Ihre materialisierten Reasons
Tabelle mit Ihren materialisierten Months
Tabelle:
SELECT Reason, Month
FROM
(
SELECT 'A' AS Reason
UNION ALL SELECT 'B'
UNION ALL SELECT 'D'
) Reasons CROSS JOIN (
SELECT 'May' AS Month
UNION ALL SELECT 'June'
UNION ALL SELECT 'July'
) Months
| REASON | MONTH | ------------------ | A | May | | B | May | | D | May | | A | June | | B | June | | D | June | | A | July | | B | July | | D | July |
Sehen Sie es auf sqlfiddle .
Sie müssen dann nur noch das Ergebnis mit Ihren zugrunde liegenden Daten verbinden:
SELECT Reason, Month, SUM(Down_time) downtime
FROM
(
SELECT 'A' AS Reason
UNION ALL SELECT 'B'
UNION ALL SELECT 'D'
) Reasons CROSS JOIN (
SELECT 'May' AS Month
UNION ALL SELECT 'June'
UNION ALL SELECT 'July'
) Months
LEFT JOIN tabledown USING (Reason, Month)
GROUP BY Reason, Month
| REASON | MONTH | DOWNTIME | ----------------------------- | A | July | 3 | | A | June | 8 | | A | May | 7 | | B | July | (null) | | B | June | 6 | | B | May | 5 | | D | July | (null) | | D | June | (null) | | D | May | (null) |
Sehen Sie es auf sqlfiddle .