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,...