Grouping Rows with GROUP BY

Grouping by NULL Values

In the examples used thus far in the tutorial our base table had no null values in it. Let's now look at grouping a table that does contain null values.

set null '(null)'

select *
from   t2
order by grp_a, grp_b ;
 
GRP_A      GRP_B             VAL
---------- ---------- ----------
A1         X1                 10
A1         X2                 40
A1         (null)             20
A1         (null)             30
A1         (null)             50
A2         (null)             60
 

Now consider the following GROUP BY query.

select grp_a, grp_b, count(*)
from   t2
group by grp_a, grp_b
order by grp_a, grp_b ;
 
GRP_A      GRP_B        COUNT(*)
---------- ---------- ----------
A1         X1                  1
A1         X2                  1
A1         (null)              3
A2         (null)              1
 

So far so good, but let's use GROUPING SETS next and see what happens.

select grp_a, grp_b, count(*)
from   t2
GROUP BY GROUPING SETS( (GRP_A, GRP_B), GRP_A )
order by grp_a, grp_b ;
 
GRP_A      GRP_B        COUNT(*)
---------- ---------- ----------
A1         X1                  1
A1         X2                  1
A1         (null)              3
A1         (null)              5
A2         (null)              1
A2         (null)              1
 

We now have two rows with "(null)" under GRP_B for each GRP_A value, one representing the null values stored in T2.GRP_B and the other representing the set of all values in T2.GRP_B.

Gotcha - NVL and NVL2

One might expect that NVL() or NVL2 could be used to distinguish the two nulls, like this

select
  grp_a
, NVL( t2.GRP_B, 'n/a' ) AS GRP_B
, nvl2( t2.grp_b, 1, 0 ) as test
, count(*)
from   t2
GROUP BY GROUPING SETS( (GRP_A, GRP_B), GRP_A )
order by grp_a, grp_b ;
 
GRP_A      GRP_B            TEST   COUNT(*)
---------- ---------- ---------- ----------
A1         X1                  1          1
A1         X2                  1          1
A1         n/a                 0          5
A1         n/a                 0          3
A2         n/a                 0          1
A2         n/a                 0          1
 

but this is not the case because functions in the SELECT list operate on an intermediate form of the result set created after the GROUP BY clause is applied, not before. In the next topic we see how the GROUPING function can help us distinguish the two types of nulls.




Linking to SQL Snippets ™

To link to this page in Oracle Technology Network Forums or OraFAQ Forums cut and paste this code.

  • [url=http://www.sqlsnippets.com/en/topic-13136.html]SQL Snippets: Grouping Rows with GROUP BY - Grouping by NULL Values[/url]

To link to this page in HTML documents or Blogger comments cut and paste this code.

  • <a href="http://www.sqlsnippets.com/en/topic-13136.html">SQL Snippets: Grouping Rows with GROUP BY - Grouping by NULL Values</a>

To link to this page in other web sites use the following values.

  • Link Text : SQL Snippets: Grouping Rows with GROUP BY - Grouping by NULL Values
  • URL (href): http://www.sqlsnippets.com/en/topic-13136.html