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

时间:2012-03-26 11:35:03

标签: sql sql-server database sql-server-2008

以下是我有的测试表的样本数据

[childId] [parentId] [present]
1         10         0
2         11         1
3         NULL       0
4         NULL       0
NULL      10         0

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

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

我得到的结果是

parentId    nbr
NULL        2
11          1

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


更新

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

我创建了一个包含完整外部联接的视图,因此我有一些NULL childId的记录和一些NULL parentId的记录。
现在,我想列出所有parentId值(NULL和非NULL),并为每个值计算所有记录,例如{{1} }。 如果我使用present=1条件,它会从结果集中删除NULL值,即where present=1我没有结果记录NULL|x
 我用parentId|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

唯一的问题(除 [parentId] [nbr] NULL 2 10 1 NULL 2 的重复记录外)是,如果没有parentId=NULLparentId=NULL的记录,结果我将不会记录{ {1}} present=1我希望列出所有parentIds,NULL | 0而不是parentId|nbr
总而言之,我需要为NULL

提供这种格式的输出
NULL

这个present=1

    [parentId]  [nbr]
    NULL        0
    10          0
    11          1

任何帮助?

4 个答案:

答案 0 :(得分:2)

where present=1 or parentId is NULL

那就是它。您有Present = 1或parentID为null。没有任何条款说parentID应为null 应为1。

你到底想要完成什么?

要列出所有存在= 1且存在所有空父ID的非null parentID,您可以使用where子句,但可以将您的组编辑为GROUP BY parentid, present。通过这种方式,您将显示所有非空值,其中包含当前值1和所有空值,均为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

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

答案 1 :(得分:2)

使用当前字段的SUM聚合,将位字段转换为整数,如下所示:

SELECT parentId, SUM(CAST(present AS INTEGER)) as nbr
FROM TestTable
GROUP BY parentId

答案 2 :(得分:0)

如果这是您正在寻找的结果:

pId    nbr
NULL   1
10     0
11     1

然后我认为这是你正在寻找的sql(尚未测试,没有可用的服务器):

select distinct 
  parentId as pId, 
  (select count(*) from TestTable where parentId=pId and present=1) as nbr
from TestTable 
group by parentId

答案 3 :(得分:0)

尝试下面提到的代码段。

SELECT ParentId, COUNT(ChildId) nbr FROM SO

其中(Present = 1)OR(ParentId为空且存在= 1) 按ParentId分组

- 或者您也可以尝试下面提到的代码。

SELECT ParentId, COUNT(ChildId) nbr FROM SO

当前= 1 按ParentId分组