Sql 在单个查询中计算空值和非空值

Sql 在单个查询中计算空值和非空值,sql,Sql,我有一张桌子 create table us ( a number ); 现在我有如下数据: a 1 2 3 4 null null null 8 9 现在,我需要一个查询来计算a列中的null和非null值a为null的元素数: select count(a) from us where a is null; a不为空的元素数: select count(a) from us where a is not null; 对于非空值 select count(a) from us 为空

我有一张桌子

create table us
(
 a number
);
现在我有如下数据:

a
1
2
3
4
null
null
null
8
9

现在,我需要一个查询来计算a列中的null非null值

a为null的元素数:

select count(a) from us where a is null;

a不为空的元素数:

select count(a) from us where a is not null;
对于非空值

select count(a)
from us
为空

select count(*)
from us

minus 

select count(a)
from us
因此

我应该做这项工作

更好的办法是列标题正确无误

SELECT COUNT(A) NOT_NULL, COUNT(*) - COUNT(A) NULLS
FROM US

在我的系统上进行的一些测试中,它需要一次完整的表扫描。

如果它是mysql,您可以尝试类似的方法

select 
   (select count(*) from TABLENAME WHERE a = 'null') as total_null, 
   (select count(*) from TABLENAME WHERE a != 'null') as total_not_null
FROM TABLENAME

下面是一个在Oracle上运行的快速而肮脏的版本:

select sum(case a when null then 1 else 0) "Null values",
       sum(case a when null then 0 else 1) "Non-null values"
from us

如果我理解正确,您希望在一列中计算所有NULL和所有NOTNULL

如果这是正确的:

SELECT count(*) FROM us WHERE a IS NULL 
UNION ALL
SELECT count(*) FROM us WHERE a IS NOT NULL
阅读注释后,编辑以获得完整查询:]



这适用于Oracle和SQL Server(您可以让它在另一个RDBMS上工作):

或:


如果您正在使用MS Sql Server

SELECT COUNT(0) AS 'Null_ColumnA_Records',
(
    SELECT COUNT(0)
    FROM your_table
    WHERE ColumnA IS NOT NULL
) AS 'NOT_Null_ColumnA_Records'
FROM your_table
WHERE ColumnA IS NULL;
我不建议你这样做。。。但这里有(结果在同一张表中)


这很有趣,但它将返回一条带有2列的记录,指示空值与非空值的计数。

使用ISNULL嵌入函数

SELECT
  COUNT_IF(a IS NULL) AS nulls,
  COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
  us


以防您希望它出现在单个记录中:

select 
  (select count(*) from tbl where colName is null) Nulls,
  (select count(*) from tbl where colName is not null) NonNulls 

;-)

这里有两种解决方案:

Select count(columnname) as countofNotNulls, count(isnull(columnname,1))-count(columnname) AS Countofnulls from table name


我有一个类似的问题:计算所有不同的值,将空值也计算为1。在这种情况下,简单计数不起作用,因为它不考虑空值

下面是一个适用于SQL的代码片段,它不涉及新值的选择。 基本上,执行distinct后,还可以使用row_number()函数返回新列(n)中的行号,然后对该列执行计数:

SELECT COUNT(n)
FROM (
    SELECT *, row_number() OVER (ORDER BY [MyColumn] ASC) n
    FROM (
        SELECT DISTINCT [MyColumn]
                    FROM [MyTable]
        ) items  
) distinctItems
试一试


简单

用于计算非空值

select count(*) from us where a is not null;
 select count(*) from us where a is null;
用于计算空值

select count(*) from us where a is not null;
 select count(*) from us where a is null;

这在T-SQL中起作用。如果您只是在计算某物的数量,并且希望包含空值,请使用COALESCE而不是case

IF OBJECT_ID('tempdb..#us') IS NOT NULL
    DROP TABLE #us

CREATE TABLE #us
    (
    a INT NULL
    );

INSERT INTO #us VALUES (1),(2),(3),(4),(NULL),(NULL),(NULL),(8),(9)

SELECT * FROM #us

SELECT CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END AS 'NULL?',
        COUNT(CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END) AS 'Count'
    FROM #us
    GROUP BY CASE WHEN a IS NULL THEN 'NULL' ELSE 'NON-NULL' END

SELECT COALESCE(CAST(a AS NVARCHAR),'NULL') AS a,
        COUNT(COALESCE(CAST(a AS NVARCHAR),'NULL')) AS 'Count'
    FROM #us
    GROUP BY COALESCE(CAST(a AS NVARCHAR),'NULL')

在阿尔贝托附近的建筑里,我加了一个汇总表

 SELECT [Narrative] = CASE 
 WHEN [Narrative] IS NULL THEN 'count_total' ELSE    [Narrative] END
,[Count]=SUM([Count]) FROM (SELECT COUNT(*) [Count], 'count_nulls' AS [Narrative]  
FROM [CrmDW].[CRM].[User]  
WHERE [EmployeeID] IS NULL 
UNION
SELECT COUNT(*), 'count_not_nulls ' AS narrative 
FROM [CrmDW].[CRM].[User] 
WHERE [EmployeeID] IS NOT NULL) S 
GROUP BY [Narrative] WITH CUBE;

我理解您的查询,您只需运行此脚本并获得Total Null,Total NotNull行

select count(*) - count(a) as 'Null', count(a) as 'Not Null' from us;

这有点棘手。假设该表只有一列,那么Count(1)和Count(*)将给出不同的值

set nocount on
    declare @table1 table (empid int)
    insert @table1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(NULL),(11),(12),(NULL),(13),(14);

    select * from @table1
    select COUNT(1) as "COUNT(1)" from @table1
    select COUNT(empid) "Count(empid)" from @table1

如图所示,第一个结果显示该表有16行。其中两行为空。因此,当我们使用Count(*)时,查询引擎对行数进行计数,因此我们得到的计数结果为16。但是在Count(empid)的情况下,它统计列empid中的非空值。所以我们得到的结果是14

因此,每当我们使用COUNT(Column)时,请确保注意空值,如下所示

select COUNT(isnull(empid,1)) from @table1
将同时计算空值和非空值


注意:即使表格由多个列组成,也同样适用。计数(1)将给出总行数,与空/非空值无关。只有当使用Count(column)对列值进行计数时,我们才需要处理空值。

通常我使用这个技巧

select sum(case when a is null then 0 else 1 end) as count_notnull,
       sum(case when a is null then 1 else 0 end) as count_null
from tab
group by a

为了提供另一种选择,Postgres 9.4+:


SQLFiddle:

所有答案要么是错误的,要么是非常过时的

执行此查询的简单而正确的方法是使用
COUNT\u IF
函数

SELECT
  COUNT_IF(a IS NULL) AS nulls,
  COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
  us
试试这个

SELECT CASE 
         WHEN a IS NULL THEN 'Null' 
         ELSE 'Not Null' 
       END a, 
       Count(1) 
FROM   us 
GROUP  BY CASE 
            WHEN a IS NULL THEN 'Null' 
            ELSE 'Not Null' 
          END 

我在postgres 10中创建了该表,以下两项都有效:

从美国选择count(*)

从我们这里选择count(a为空)

在我的例子中,我希望在多个列中使用“空分布”

SELECT
       (CASE WHEN a IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS a_null,
       (CASE WHEN b IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS b_null,
       (CASE WHEN c IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS c_null,
       ...
       count(*)
FROM us
GROUP BY 1, 2, 3,...
ORDER BY 1, 2, 3,...

根据“…”可以很容易地扩展到更多的列,可以根据需要扩展到更多的列。

嗨,你需要在哪里使用这种计数数据库代码?我们谈论的是哪种语言的数据库?IordanI很惊讶没有一个单一的答案包含一个简单的select count(*)…@Lieven:你到底为什么要在这里使用
union
?Montecristo的答案是目前为止最好的解决方案,因为OP希望它只需要一个查询。蒙特克里斯托的答案确实是迄今为止最好的解决方案。。。他只需要加上工会:)这就是我读标题得到的。会编辑的。好肉汁,伙计,看看这些查询的执行计划。您正在启动表的左右扫描,特别是在这样一个非常简单的语句(
select count(*)from t where a is null
)中。我手头没有一个数据库可以查看,但列是否被索引。如果是,它是通过范围扫描发生的,否则,您几乎只剩下一个完整的表扫描。在oracle中,空值不存储在索引中,因此我怀疑您的示例并没有更好。您的milage可能非常有用:只有当您不向后拉>~10%的行时,索引才有用。然后,启动完整扫描。在这种情况下,你至少会得到一次扫描,如果不是两次的话。当每个答案都不是这个时,我感到震惊。是的,但不是。我想他只想在一个查询中得到NULL和notnull的数字。。。你在两个问题中提出了如何做到这一点…@romaintaz:完全正确。我把标题读作问题。在五次编辑中,没有人想到修复它。是的。@romaintaz:是的,你是对的,我把这当作“运行一次查询以发现我们有多少空值”,我甚至不知道为什么要更正,谢谢。@Montecristo:因为标题只要求计算
null
:)类似的语法在SQL Server中也可以使用。而且,这样做只会扫描表一次;联合解决方案将执行两次表扫描。与小型表无关,对于大型表非常重要。SQL Server的唯一更改是“空值”必须变成
“空值”
。单引号,而不是双引号。SQLServer对此查询使用索引扫描,而不是使用并集进行两次索引查找。在具有40.000行的表上,没有速度差。在具有11.332.581行的表上,有两个表扫描,没有明显的sp
select COUNT(isnull(empid,1)) from @table1
select sum(case when a is null then 0 else 1 end) as count_notnull,
       sum(case when a is null then 1 else 0 end) as count_null
from tab
group by a
SELECT
  COUNT(*) FILTER (WHERE a IS NULL) count_nulls,
  COUNT(*) FILTER (WHERE a IS NOT NULL) count_not_nulls
FROM us;
SELECT
    ALL_VALUES
    ,COUNT(ALL_VALUES)
FROM(
        SELECT 
        NVL2(A,'NOT NULL','NULL') AS ALL_VALUES 
        ,NVL(A,0)
        FROM US
)
GROUP BY ALL_VALUES
SELECT
  COUNT_IF(a IS NULL) AS nulls,
  COUNT_IF(a IS NOT NULL) AS not_nulls
FROM
  us
SELECT CASE 
         WHEN a IS NULL THEN 'Null' 
         ELSE 'Not Null' 
       END a, 
       Count(1) 
FROM   us 
GROUP  BY CASE 
            WHEN a IS NULL THEN 'Null' 
            ELSE 'Not Null' 
          END 
SELECT
       (CASE WHEN a IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS a_null,
       (CASE WHEN b IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS b_null,
       (CASE WHEN c IS NULL THEN 'NULL' ELSE 'NOT-NULL' END) AS c_null,
       ...
       count(*)
FROM us
GROUP BY 1, 2, 3,...
ORDER BY 1, 2, 3,...