使用 where 和 group by 子句计算 sql 中的空值

dra*_*vic 5 sql database sql-server sql-server-2008

这是我拥有的测试表的示例数据

[childId] [parentId] [present]
1         10         0
2         11         1
3         NULL       0
4         NULL       0
NULL      10         0
Run Code Online (Sandbox Code Playgroud)

现在,对于所有的 parentIds(包括那些为 NULL 的),我想计算所有当前的 childIds

select parentId, count(childId) as nbr
from TestTable
where present=1 or parentId is NULL
group by parentId
Run Code Online (Sandbox Code Playgroud)

我得到的结果是

parentId    nbr
NULL        2
11          1
Run Code Online (Sandbox Code Playgroud)

nbr我为 present=1 和 present=0 得到相同的计数数 ( )。似乎我不能对NULL分组值强加条件。
我犯了什么错误,我想提出的查询的解决方案是什么?


更新

由于我给出的测试用例不具有代表性,在我以更好的方式重现真实情况之前,我将尝试解释我所面临的问题。

我创建了一个带有完整外连接的视图,所以我有一些记录有NULLforchildId和一些记录有NULLfor parentId
现在,我想列出所有parentId值(包括NULL和非NULL),并为每个值计算所有记录,例如,具有present=1. 如果我使用where present=1的条件,它消除了从结果集中NULL值,即我不会有结果记录NULL|xparentId|nbr
我用union all. 在第一个选择中我有where present=1,在第二个选择中我有where 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
Run Code Online (Sandbox Code Playgroud)

我得到的结果是

    [parentId]  [nbr]
    NULL        2
    10          1
    NULL        2
Run Code Online (Sandbox Code Playgroud)

唯一的问题(除了 for 的重复记录parentId=NULL)是,如果没有带parentId=NULLand 的记录present=1,结果我不会有NULL | 0for 的记录,parentId|nbr我想列出所有 parentIds, bothNULL和 not NULL
所以总而言之,我需要有这种格式的输出present=1

    [parentId]  [nbr]
    NULL        0
    10          0
    11          1
Run Code Online (Sandbox Code Playgroud)

而这个是为了 present=0

    [parentId]  [nbr]
    NULL        2
    10          2
    11          0
Run Code Online (Sandbox Code Playgroud)

有什么帮助吗?

cai*_*rnz 2

where present=1 or parentId is NULL
Run Code Online (Sandbox Code Playgroud)

就这样了。您的 Present = 1 或 ParentID 为空。没有子句规定parentID应该为null并且present应该为1。

您到底想实现什么目标?

要列出所有具有present = 1的非空parentID以及所有空parentID(无论是否存在),您可以使用where子句,但将您的group by编辑为GROUP BY parentid, present。这样,您将显示所有非 null 且都存在 1,以及所有 null,同时存在 0 和 1。

更新:根据您的新要求,您还需要对不存在的组合进行分组。您的数据集中没有任何地方存在 NULL、1 值 - 因此您查看它的常规方式没有多大意义。您需要将parentid 和present 彼此分开。

执行此操作的一种方法是简单地执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)

这是基于使用 sqlfiddle 和您的示例数据集进行的测试。http://sqlfiddle.com/#!3/8d7f6/29