sql >> Base de Datos >  >> RDS >> Mysql

Consulta MySql para obtener todas las combinaciones de dos columnas con NULL si no hay un registro coincidente

Tu primera combinación externa , como se esperaba, produce:

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

Sin embargo, debido a que las uniones externas producen resultados si la condición de unión se cumple al menos una vez (y solo introducir NULL registra si la condición es nunca satisfecho), su segunda combinación externa entonces no producir un registro para (B, July); también suelta Reason = 'D' por completo, porque no se cumple la condición de unión (y los tres meses se han cumplido en otro lugar):

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

Mientras que podrías resolver la pérdida de Reason = 'D' añadiendo OR a.Month IS NULL a su condición de unión, todavía no producirá (B, July) . En cambio, porque desea obtener cada par de (Reason, Month) , debe CROSS JOIN tus Reasons materializadas tabla con tus Months materializados tabla:

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 |

Véalo en sqlfiddle .

Entonces simplemente necesita unir externamente el resultado con sus datos subyacentes:

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

Véalo en sqlfiddle .