Подтвердить что ты не робот

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.

4b9b3361

Ответ 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