counting null values in sql with where and group by clause
Solution 1
where present=1 or parentId is NULL
That would be it. Either you have Present = 1 or parentID is null. There's no clause saying that parentID should be null and present should be 1.
What exactly are you trying to accomplish?
To list all non-null parentID that has present = 1 and all null parentID regardless of present, you can use your where clause, but edit your group by to GROUP BY parentid, present
. This way you will show all non-null with present 1, and all null, both present 0 and 1.
UPDATE: Based on your new requirements, you need to also group for non-existing combinations. Nowhere in your dataset is there a NULL, 1 value - so your ordinary way of looking at it won't make much sense. You need to separate the parentid and present from eachother.
One way to do this is to simply do the following:
SELECT parentID, Pres1.nbr_pres_1, Pres0.nbr_pres_0
FROM t
OUTER APPLY (SELECT COUNT(1) as nbr_pres_1 FROM t t1 WHERE
coalesce( t.parentid , -999) = coalesce(t1.parentid ,-999) and present=1 ) Pres1
OUTER APPLY (SELECT COUNT(1) as nbr_pres_0 FROM t t0 WHERE
coalesce( t.parentid , -999) = coalesce(t0.parentid ,-999) and present=0 ) Pres0
GROUP BY t.ParentID, Pres1.nbr_pres_1, Pres0.nbr_pres_0
This is based on testing using sqlfiddle and your sample data set. http://sqlfiddle.com/#!3/8d7f6/29
Solution 2
Use a SUM aggregation of the present field, casting the bit field to integer, as follows:
SELECT parentId, SUM(CAST(present AS INTEGER)) as nbr
FROM TestTable
GROUP BY parentId
Solution 3
If this is the result you are looking for:
pId nbr
NULL 1
10 0
11 1
Then I think this is the sql you are looking for(not tested yet, no server available):
select distinct
parentId as pId,
(select count(*) from TestTable where parentId=pId and present=1) as nbr
from TestTable
group by parentId
dragan.stepanovic
craft. tdd. xp. design. architecture. ddd/cqrs/es.
Updated on March 28, 2020Comments
-
dragan.stepanovic about 4 years
Here is the sample data for test table I have
[childId] [parentId] [present] 1 10 0 2 11 1 3 NULL 0 4 NULL 0 NULL 10 0
Now, for all the parentIds (including those with NULL) I want to count all the present childIds
select parentId, count(childId) as nbr from TestTable where present=1 or parentId is NULL group by parentId
The result I get is
parentId nbr NULL 2 11 1
Same count number (
nbr
) I get for both present=1 and present=0. It seems that I cannot impose a condition for theNULL
grouped value.
What's the mistake I'm making and what's the solution for the query I want to make?
UPDATE:
Since the test case I gave is not representative, until I recreate the real situation in better way, I'll try to explain the problem I'm facing.
I created a view with full outer join, so I have some records having
NULL
forchildId
and some records havingNULL
forparentId
.
Now, I want to list all of theparentId
values (bothNULL
and nonNULL
) and for each of them, count all the records that, for example, havepresent=1
. If I usewhere present=1
condition, it eliminates NULL values from result set, i.e. I won't have result recordNULL|x
forparentId|nbr
.
I solved this withunion all
. In first select I havewhere present=1
and in second select I havewhere present=1 and parentId is NULL
.select parentId, count(childId) as nbr from TestTable where present=0 group by parentId union all select parentId, count(childId) as nbr from TestTable where present=0 and parentId is NULL group by parentId
The result I get is
[parentId] [nbr] NULL 2 10 1 NULL 2
The only problem with this (besides duplicated record for
parentId=NULL
), is that if there are no records withparentId=NULL
andpresent=1
, in result I won't have record withNULL | 0
forparentId|nbr
and I want to list ALL parentIds, bothNULL
and notNULL
.
So to sum it up I need to have this format of output forpresent=1
[parentId] [nbr] NULL 0 10 0 11 1
and this one for
present=0
[parentId] [nbr] NULL 2 10 2 11 0
Any help?