Twoje pierwsze sprzężenie zewnętrzne , zgodnie z oczekiwaniami, daje:
| REASON | MONTH | ------------------- | A | May | | A | May | | A | July | | A | June | | B | May | | B | June | | D | (null) |
Jednak ponieważ złączenia zewnętrzne dają wyniki, jeśli warunek złączenia jest spełniony przynajmniej raz (i wprowadź tylko NULL
zapisuje, jeśli stan jest nigdy zadowolony), Twoje drugie sprzężenie zewnętrzne
to nie utworzyć rekord dla (B, July)
; spada również Reason = 'D'
całkowicie, ponieważ warunek dołączenia nie jest spełniony (a wszystkie trzy miesiące zostały spełnione gdzie indziej):
| REASON | MONTH | ------------------ | A | May | | A | May | | B | May | | A | June | | B | June | | A | July |
Podczas gdy mogłeś rozwiązać utratę Reason = 'D'
przez dodanie
OR a.Month IS NULL
do warunku dołączenia, nadal nie wyprodukujesz (B, July)
. Zamiast tego, ponieważ chcesz uzyskać każdą parę (Reason, Month)
, musisz CROSS JOIN
Twoje zmaterializowane Reasons
tabela ze zmaterializowanymi Months
tabela:
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 |
Zobacz go na sqlfiddle .
Następnie potrzebujesz jedynie zewnętrznego połączenia wyniku z danymi bazowymi:
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) |
Zobacz go na sqlfiddle .