Ich versuche, mithilfe der Funktion group by eine Methode zu finden, mit der Ergebnisse zurückgegeben werden können.
GROUP BY funktioniert wie erwartet, aber meine Frage lautet: Ist es möglich, das NULL-Feld von group by ignore zu ignorieren? Damit es keine NULL-Werte gruppiert, brauche ich immer noch alle Zeilen, in denen das angegebene Feld NULL ist.
SELECT `table1`.*,
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`
FROM `table1`
WHERE (enabled = 1)
GROUP BY `ancestor`
Nehmen wir also an, ich habe 5 Zeilen und das Vorfahrenfeld ist NULL. Es gibt 1 Zeile zurück. Aber ich möchte alle 5 Zeilen.
Vielleicht sollten Sie den Nullspalten etwas hinzufügen, um sie eindeutig zu machen und sie danach zu gruppieren? Ich habe nach einer Sequenz gesucht, die anstelle von UUID () verwendet werden kann, aber dies könnte genauso gut funktionieren.
SELECT `table1`.*,
IFNULL(ancestor,UUID()) as unq_ancestor
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`
FROM `table1`
WHERE (enabled = 1)
GROUP BY unq_ancestor
Bei der Gruppierung nach Spalte Y
werden alle Zeilen, für die der Wert in Y
NULL
ist, zusammen gruppiert.
Dieses Verhalten ist durch den SQL-2003-Standard definiert , obwohl es etwas überraschend ist, weil NULL
nicht gleich NULL
ist.
Sie können dies umgehen, indem Sie einen anderen Wert gruppieren, einige Funktion (mathematisch gesehen) der Daten in Ihrer Gruppierungsspalte.
Wenn Sie eine eindeutige Spalte X
haben, ist dies einfach.
X Y
-------------
1 a
2 a
3 b
4 b
5 c
6 (NULL)
7 (NULL)
8 d
SELECT GROUP_CONCAT(`X`)
FROM `tbl`
GROUP BY `Y`;
Ergebnis:
GROUP_CONCAT(`foo`)
-------------------
6,7
1,2
3,4
5
8
SELECT GROUP_CONCAT(`X`)
FROM `tbl`
GROUP BY IFNULL(`Y`, `X`);
Ergebnis:
GROUP_CONCAT(`foo`)
-------------------
6
7
1,2
3,4
5
8
SELECT GROUP_CONCAT(`X`), IFNULL(`Y`, `X`) AS `grp`
FROM `tbl`
GROUP BY `grp`;
Ergebnis:
GROUP_CONCAT(`foo`) `grp`
-----------------------------
6 6
7 7
1,2 a
3,4 b
5 c
8 d
Wenn Sie keine eindeutige Spalte haben, die Sie verwenden können, können Sie versuchen, stattdessen einen eindeutigen Platzhalterwert zu generieren. Ich überlasse dies dem Leser als Übung.
GROUP BY IFNULL(required_field, id)
SELECT table1.*,
GROUP_CONCAT(id SEPARATOR ',') AS children_ids
FROM table1
WHERE (enabled = 1)
GROUP BY ancestor
, CASE WHEN ancestor IS NULL
THEN table1.id
ELSE 0
END
Möglicherweise schnellere Version der vorherigen Lösung, falls Sie eine eindeutige Kennung in Tabelle1 haben (nehmen wir an, es ist Tabelle1.id):
SELECT `table1`.*,
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`,
IF(ISNULL(ancestor),table1.id,NULL) as `do_not_group_on_null_ancestor`
FROM `table1`
WHERE (enabled = 1)
GROUP BY `ancestor`, `do_not_group_on_null_ancestor`