Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GROUP BY - do not group NULL

I'm trying to figure out a way to return results by using the group by function.

GROUP BY is working as expected, but my question is: Is it possible to have a group by ignoring the NULL field. So that it does not group NULLs together because I still need all the rows where the specified field is NULL.

SELECT `table1`.*,      GROUP_CONCAT(id SEPARATOR ',') AS `children_ids` FROM `table1`  WHERE (enabled = 1)  GROUP BY `ancestor`  

So now let's say I have 5 rows and the ancestor field is NULL, it returns me 1 row....but I want all 5.

like image 224
slik Avatar asked Jan 03 '11 22:01

slik


2 Answers

Perhaps you should add something to the null columns to make them unique and group on that? I was looking for some sort of sequence to use instead of UUID() but this might work just as well.

SELECT `table1`.*,      IFNULL(ancestor,UUID()) as unq_ancestor     GROUP_CONCAT(id SEPARATOR ',') AS `children_ids` FROM `table1`  WHERE (enabled = 1)  GROUP BY unq_ancestor 
like image 113
bot403 Avatar answered Sep 23 '22 16:09

bot403


When grouping by column Y, all rows for which the value in Y is NULL are grouped together.

This behaviour is defined by the SQL-2003 standard, though it's slightly surprising because NULL is not equal to NULL.

You can work around it by grouping on a different value, some function (mathematically speaking) of the data in your grouping column.

If you have a unique column X then this is easy.


Input

X      Y ------------- 1      a 2      a 3      b 4      b 5      c 6      (NULL) 7      (NULL) 8      d 

Without fix

SELECT GROUP_CONCAT(`X`)   FROM `tbl`  GROUP BY `Y`; 

Result:

GROUP_CONCAT(`foo`) ------------------- 6,7 1,2 3,4 5 8 

With fix

SELECT GROUP_CONCAT(`X`)   FROM `tbl`  GROUP BY IFNULL(`Y`, `X`); 

Result:

GROUP_CONCAT(`foo`) ------------------- 6 7 1,2 3,4 5 8 

Let's take a closer look at how this is working

SELECT GROUP_CONCAT(`X`), IFNULL(`Y`, `X`) AS `grp`   FROM `tbl`  GROUP BY `grp`; 

Result:

GROUP_CONCAT(`foo`)     `grp` ----------------------------- 6                       6 7                       7 1,2                     a 3,4                     b 5                       c 8                       d 

If you don't have a unique column that you can use, you can try to generate a unique placeholder value instead. I'll leave this as an exercise to the reader.

like image 39
Lightness Races in Orbit Avatar answered Sep 20 '22 16:09

Lightness Races in Orbit