Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consulta MySql para obter todas as combinações de duas colunas com NULL se não houver registro correspondente


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 .