GROUP BY – 不要将NULL分组

我试图找出一种方法来返回结果通过使用function组。

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。

也许你应该添加一些东西到空列,使他们独特和组? 我正在寻找某种顺序来使用,而不是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 

按列Y分组时, Y中的值为NULL所有行都组合在一起。

这个行为是由SQL-2003标准定义的 ,虽然它有点令人惊讶,因为NULL不等于NULL

您可以通过对不同的值进行分组,在分组列中使用某些函数 (从mathangular度来说)数据。

如果你有一个独特的列X那么这很容易。


input

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

如果您没有可以使用的唯一列,则可以尝试生成唯一的占位符值。 我会把这个作为练习留给读者。

也许以前的解决scheme的更快的版本,以防在table1中有唯一的标识符(假设它是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` 
 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 

GROUP BY IFNULL(required_field, id)