/ / Puis-je grouper par MySQL, mais lui faire ignorer les valeurs NULL lors du regroupement, en supprimant une ligne de résultat si nécessaire? - mysql, group-by, left-join

Puis-je grouper par MySQL, mais lui faire ignorer les valeurs NULL lors du regroupement, en supprimant une ligne de résultat si nécessaire? - mysql, group-by, left-join

Mes tables:

t1

col_a  col_b
1       100
1       200
1       300
2       400

t2

col_a  col_b
100      5
100      6

t3

col_a  col_b
5       100
6       200
6       300

Si je lance une requête et quitte à rejoindre les 3 tables dans l'ordre je reçois:

1   100  5     100
1   100  6     200
1   100  6     300
1   200  null  null
1   300  null  null
2   400  null  null

Si j'ajoute un groupe par t1.col_a, t2.col_b:

1   100           5      100
1   100           6      (200 or 300)
1   (200 or 300)  null   null
2   400           null   null

Mais je ne veux pas que la 3ème ligne soit affichée car elle n’a pas de valeur dans t2.col_b. Je pourrais ajouter une condition à laquelle cette colonne n’est pas nulle, mais cela supprimerait la dernière ligne qui doit rester.

Dans une requête parfaite, j'aimerais voir:

1   100           5      100
1   100           6      (200 or 300)
2   400           null   null

Réponses:

0 pour la réponse № 1

Essaye celui-là. t1.col_b est un peu délicat, car s'il existe plusieurs valeurs t1.col_a sans aucune référence à t2, cette requête sélectionne une variable aléatoire pour cela.

SELECT
sub.col_a,
IFNULL(sub.relation,t1.col_b),
t2.col_b,
t3.col_b
FROM(
SELECT
t1.col_a,
group_concat(DISTINCT t2.col_a) AS relation
FROM table1 AS t1
LEFT JOIN table2 AS t2 ON t2.col_a = t1.col_b
GROUP BY t1.col_a
) AS sub
LEFT JOIN table1 AS t1
ON t1.col_a = sub.col_a
AND (t1.col_b IN (sub.relation) OR sub.relation IS NULL)
LEFT JOIN table2 AS t2
ON t2.col_a = t1.col_b
LEFT JOIN table3 AS t3
ON t3.col_a = t2.col_b
GROUP BY t1.col_a, t2.col_b

0 pour la réponse № 2

Une solution consiste à sélectionner uniquement les lignes non nulles dans le résultat, puis à les unir avec un ensemble de résultats plus large, mais groupé:

SELECT * FROM t1
JOIN t2 ON t1.col_b = t2.col_a
LEFT JOIN t3 ON t2.col_b = t3.col_a

UNION

SELECT * FROM t1
LEFT JOIN t2 ON t1.col_b = t2.col_a
LEFT JOIN t3 ON t2.col_b = t3.col_a
GROUP BY t1.col_a

Notez que la première requête n'a pas de jointure à gauche. C’est parce que nous ne voulons pas de résultats NULL dans cette requête. Cette requête vous donne:

t1.col_a    t2.col_a    t3.col_a    t3.col_b
1           100          5         100
1           100          6         200
1           100          6         300

Et la deuxième requête vous donne:

t1.col_a    t2.col_a    t3.col_a    t3.col_b
1           100          5         100
2           400         NULL       NULL

Enfin, lorsque vous effectuez une union, elle supprime le résultat en double (la première ligne du premier jeu de résultats est égale à la première ligne du deuxième jeu de résultats). C’est le comportement par défaut du Commande UNION, résultant en:

t1.col_a    t2.col_a    t3.col_a    t3.col_b
1           100          5         100
1           100          6         200
1           100          6         300
2           400         NULL       NULL