我有一个包含processed_timestamp
列的表 - 如果已经处理了一条记录,那么该字段包含处理它的日期时间,否则它为空。
我想写一个返回两行的查询:
NULL xx -- count of records with null timestamps
NOT NULL yy -- count of records with non-null timestamps
这可能吗?
更新:表格非常大,因此效率非常重要。我可以运行两个查询来分别计算每个总数,但是如果我可以避免它,我想避免两次击中表。
答案 0 :(得分:43)
在MySQL中,您可以执行类似
的操作SELECT
IF(ISNULL(processed_timestamp), 'NULL', 'NOT NULL') as myfield,
COUNT(*)
FROM mytable
GROUP BY myfield
答案 1 :(得分:38)
在T-SQL(MS SQL Server)中,这可以工作:
SELECT
CASE WHEN Field IS NULL THEN 'NULL' ELSE 'NOT NULL' END FieldContent,
COUNT(*) FieldCount
FROM
TheTable
GROUP BY
CASE WHEN Field IS NULL THEN 'NULL' ELSE 'NOT NULL' END
答案 2 :(得分:23)
甲骨文:
按nvl2分组(字段,'NOT NULL','NULL')
答案 3 :(得分:21)
尝试以下方法,它是供应商中立的:
select
'null ' as type,
count(*) as quant
from tbl
where tmstmp is null
union all
select
'not null' as type,
count(*) as quant
from tbl
where tmstmp is not null
让我们的本地DB2专家看一下之后,他同意:迄今为止没有提供的解决方案(包括这个解决方案)可以避免全表扫描(如果时间戳没有被索引,则表格为表格,或者是索引)。它们都扫描表中的每个记录一次。
所有CASE / IF / NVL2()解决方案都为每一行执行空到字符串转换,从而在DBMS上引入了不必要的负载。这个解决方案没有这个问题。
答案 4 :(得分:5)
如果是oracle,那么你可以这样做:
select decode(field,NULL,'NULL','NOT NULL'), count(*)
from table
group by decode(field,NULL,'NULL','NOT NULL');
我确信其他数据库允许类似的技巧。
答案 5 :(得分:5)
斯图尔特
也许考虑这个解决方案。它(也是!)供应商非特定。
SELECT count([processed_timestamp]) AS notnullrows,
count(*) - count([processed_timestamp]) AS nullrows
FROM table
至于效率,这可以通过在一行中包含结果来避免2x索引搜索/表扫描/任何事情。如果你在结果中绝对需要2行,那么由于联合聚合,两次遍历集合可能是不可避免的。
希望这有帮助
答案 6 :(得分:1)
另一种MySQL方法是使用CASE
operator,它可以推广到IF()
以外的其他选择:
SELECT CASE WHEN processed_timestamp IS NULL THEN 'NULL'
ELSE 'NOT NULL' END AS a,
COUNT(*) AS n
FROM logs
GROUP BY a
答案 7 :(得分:1)
如果您的数据库对表有一个有效的COUNT(*)函数,您可以COUNT较小的数字,并减去。
答案 8 :(得分:1)
SQL Server(从2012年开始):
SELECT IIF(ISDATE(processed_timestamp) = 0, 'NULL', 'NON NULL'), COUNT(*)
FROM MyTable
GROUP BY ISDATE(processed_timestamp);
答案 9 :(得分:0)
我个人喜欢Pax的解决方案,但是如果你只需要返回一行(就像我最近一样),在MS SQL Server 2005/2008中你可以使用CTE“堆叠”这两个查询
with NullRows (countOf)
AS
(
SELECT count(*)
FORM table
WHERE [processed_timestamp] IS NOT NULL
)
SELECT count(*) AS nulls, countOf
FROM table, NullRows
WHERE [processed_timestamp] IS NULL
GROUP BY countOf
希望这有帮助
答案 10 :(得分:0)
[T-SQL]:
select [case], count(*) tally
from (
select
case when [processed_timestamp] is null then 'null'
else 'not null'
end [case]
from myTable
) a
您可以在案例陈述中添加您想要形成分区的其他任何值,例如:今天,昨天,中午和下午2点,周四下午6点之后。
答案 11 :(得分:0)
Select Sum(Case When processed_timestamp IS NULL
Then 1
Else 0
End) not_processed_count,
Sum(Case When processed_timestamp Is Not NULL
Then 1
Else 0
End) processed_count,
Count(1) total
From table
编辑:没有仔细阅读,这一行返回一行。
答案 12 :(得分:0)
在Oracle中
SELECT COUNT(*), COUNT(TIME_STAMP_COLUMN)
FROM TABLE;
count(*)返回所有行的计数
count(column_name)返回非NULL的行数,所以
SELECT COUNT(*) - COUNT(TIME_STAMP_COLUMN) NUL_COUNT,
COUNT(TIME_STAMP_COLUMN) NON_NUL_COUNT
FROM TABLE
应该做这个工作。
如果列已编入索引,您最终可能会进行某种范围扫描并避免实际读取该表。
答案 13 :(得分:0)
T-sql(sql-server)的另一种方式
select count(case when t.timestamps is null
then 1
else null end) NULLROWS,
count(case when t.timestamps is not null
then 1
else null end) NOTNULLROWS
from myTable t