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

标签 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 分组值强加条件。
我犯了什么错误,我想提出的查询的解决方案是什么?


更新:

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

我创建了一个具有完全外部连接的 View ,所以我有一些记录具有 NULLchildId 和一些具有 NULL 的记录 parentId.
现在,我想列出所有 parentId 值(包括 NULL 和非 NULL),并为它们中的每一个计算所有记录,例如,有 present=1。 如果我使用 where present=1 条件,它会从结果集中消除 NULL 值,即我不会有 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=NULL 的重复记录)是,如果没有 parentId=NULLpresent=1 的记录,结果我不会有 NULL | 的记录0 对于 parentId|nbr 我想列出所有 parentIds,包括 NULL 而不是 NULL
所以总而言之,我需要为 present=1

提供这种格式的输出
    [parentId]  [nbr]
    NULL        0
    10          0
    11          1

而这个是 present=0

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

有什么帮助吗?

最佳答案

where present=1 or parentId is NULL

就是这样。 Present = 1 或 parentID 为空。没有条款说 parentID 应该是 null and present 应该是 1。

你到底想完成什么?

要列出所有 present = 1 的非空 parentID 和所有 null parentID 而不管 present,您可以使用 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

关于sql - 使用 where 和 group by 子句计算 sql 中的空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9871368/

相关文章:

sql - 使用oracle sql中的窗口函数检查分区中是否存在值

sql - 在没有 JSON_VALUE 的 SQL 中获取 json 值

mysql - 具有树状数据的表的数据库规范化

php - 从一个表中选择多个数据并使用PHP表单插入到另一个表中

php - 在 php 中获取时,CSS 样式不起作用

php - 从一个表中获取列引用在另一个表中没有的唯一行

mysql - 无法访问 mySQL Workbench 的端口 3306

sql - 将 varchar 值 'PK3' 转换为数据类型 int 时转换失败

sql - 满足条件的 COUNT 行(在具有特定条件的行处重置)

sql-server - SQLServerException : "The result set is closed" when using Streams as return type