GROUP BY - не группировать NULL
Я пытаюсь найти способ вернуть результаты, используя группу по функциям.
GROUP BY работает так, как ожидалось, но мой вопрос: возможно ли иметь группу, игнорируя поле NULL. Так что он не группирует NULL вместе, потому что мне все еще нужны все строки, где указанное поле равно NULL.
SELECT `table1`.*,
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`
FROM `table1`
WHERE (enabled = 1)
GROUP BY `ancestor`
Итак, теперь скажем, что у меня 5 строк, а поле предков - NULL, оно возвращает мне 1 строку.... но я хочу все 5.
Ответы
Ответ 1
Возможно, вам нужно добавить что-то в нулевые столбцы, чтобы сделать их уникальными и сгруппироваться по этому поводу? Я искал какую-то последовательность для использования вместо UUID(), но это может работать так же хорошо.
SELECT `table1`.*,
IFNULL(ancestor,UUID()) as unq_ancestor
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`
FROM `table1`
WHERE (enabled = 1)
GROUP BY unq_ancestor
Ответ 2
При группировке по столбцу Y
все строки, для которых значение в Y
равно NULL
, группируются вместе.
Это поведение определено стандартом SQL-2003, хотя это несколько удивительно, потому что NULL
не равно NULL
.
Вы можете обойти это, группируя другое значение, некоторые функции (математически говоря) данных в столбце группировки.
Если у вас есть уникальный столбец X
, тогда это будет легко.
Ввод
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`;
Результат:
GROUP_CONCAT(`foo`)
-------------------
6,7
1,2
3,4
5
8
С исправлением
SELECT GROUP_CONCAT(`X`)
FROM `tbl`
GROUP BY IFNULL(`Y`, `X`);
Результат:
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`;
Результат:
GROUP_CONCAT(`foo`) `grp`
-----------------------------
6 6
7 7
1,2 a
3,4 b
5 c
8 d
Если у вас нет уникального столбца, который вы можете использовать, вы можете попытаться создать уникальное значение-заполнитель вместо этого. Я оставлю это как упражнение для читателя.
Ответ 3
GROUP BY IFNULL(required_field, id)
Ответ 4
Возможно, более быстрая версия предыдущего решения в случае, если у вас есть уникальный идентификатор в таблице1 (предположим, что это table1.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`
Ответ 5
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