GROUP BY - 不分组NULL

时间:2011-01-03 22:22:44

标签: mysql sql group-by

我正试图找出一种通过按功能分组来返回结果的方法。

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行。

6 个答案:

答案 0 :(得分:57)

也许您应该在空列中添加一些东西以使它们唯一并对其进行分组?我一直在寻找使用某种序列而不是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

答案 1 :(得分:36)

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

This behaviour is defined by the SQL-2003 standard,虽然有点令人惊讶,因为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

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

答案 2 :(得分:17)

GROUP BY IFNULL(required_field, id)

答案 3 :(得分:9)

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

答案 4 :(得分:6)

如果你在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`

答案 5 :(得分:0)

要合并多个表和group_concat(唯一主键或外键)列的不同列和列总和以在同一行中显示值

select column1,column2,column3,GROUP_CONCAT(if(column4='', null, column4)) as 
column4,sum(column5) as column5
from (
      select column1,group_concat(column2) as column2,sum(column3 ) as column3,'' as 
      column4,'' as column5
      from table1 
      group by column1

      union all

      select column1,'' as column2,'' as column3,group_concat(column4) as 
      column4,sum(column5) as column5
      from table 2 
      group by column1
     ) as t
     group by column1