Mysql
 sql >> Base de données >  >> RDS >> Mysql

Requête MySql pour obtenir toutes les combinaisons de deux colonnes avec NULL s'il n'y a pas d'enregistrement correspondant

Votre première jointure externe , comme prévu, produit :

| REASON |  MONTH |
-------------------
|      A |    May |
|      A |    May |
|      A |   July |
|      A |   June |
|      B |    May |
|      B |   June |
|      D | (null) |

Cependant, comme les jointures externes produisent des résultats si la condition de jointure est satisfaite au moins une fois (et n'introduire que NULL enregistre si la condition est jamais satisfait), votre deuxième jointure externe alors pas produire un enregistrement pour (B, July); il supprime également Reason = 'D' entièrement, car la condition de jointure n'est pas remplie (et les trois mois ont été satisfaits ailleurs) :

| REASON | MONTH |
------------------
|      A |   May |
|      A |   May |
|      B |   May |
|      A |  June |
|      B |  June |
|      A |  July |

Alors que vous pourriez résoudre la perte de Reason = 'D' en ajoutant OR a.Month IS NULL à votre condition de jointure, vous ne produirez toujours pas (B, July) . Au lieu de cela, parce que vous voulez obtenir chaque paire de (Reason, Month) , vous devez CROSS JOIN vos Reasons matérialisées tableau avec vos Months matérialisés tableau :

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 |

Voir sur sqlfiddle .

Il vous suffit alors d'effectuer une jointure externe entre le résultat et vos données sous-jacentes :

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) |

Voir sur sqlfiddle .