Sua primeira junção externa , como esperado, produz:
| REASON | MONTH | ------------------- | A | May | | A | May | | A | July | | A | June | | B | May | | B | June | | D | (null) |
No entanto, como as junções externas produzem resultados se a condição de junção for satisfeita pelo menos uma vez (e apenas introduza
NULL
registros se a condição for nunca satisfeito), sua segunda junção externa
então não produzir um registro para (B, July)
; ele também descarta Reason = 'D'
inteiramente, porque a condição de junção não foi atendida (e todos os três meses foram satisfeitos em outro lugar):| REASON | MONTH | ------------------ | A | May | | A | May | | B | May | | A | June | | B | June | | A | July |
Enquanto você poderia resolver a perda de
Reason = 'D'
adicionando
OR a.Month IS NULL
à sua condição de ingresso, você ainda não produzirá (B, July)
. Em vez disso, porque você deseja obter todos os pares de (Reason, Month)
, você deve CROSS JOIN
suas Reasons
materializadas tabela com seus Months
materializados 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 |
Veja em sqlfiddle .
Você então precisa apenas da junção externa do resultado com seus dados subjacentes:
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) |
Veja em sqlfiddle .