如何计算每列中有多少个空值?
Posted
技术标签:
【中文标题】如何计算每列中有多少个空值?【英文标题】:How to calculate how many null values are present in each column? 【发布时间】:2019-04-30 14:03:51 【问题描述】:我有一张这样的桌子:
col1
col2
col3
1
0
null
null
null
null
3
null
null
null
5
1
我希望在 Oracle 10G 中得到这样的输出:
column_name
null_count
col1
2
col2
2
col3
@ 987654343@
我使用 UNION ALL 实现了这一点,如下所示:
select "col1" column_name,sum(case when col1 is null then 1 else 0 end) as null_count from A group by "col1"
union all
select "col2" column_name,sum(case when col2 is null then 1 else 0 end) as null_count from A group by "col2"
union all
select "col3" column_name,sum(case when col3 is null then 1 else 0 end) as null_count from A group by "col3";
它工作正常,但需要很多时间,因为有将近 100 个 UNION ALL。我想在不使用 UNION ALL 的情况下获得相同的输出。
有什么方法可以在不使用 UNION ALL 的情况下实现这一点?
【问题讨论】:
【参考方案1】:您可以为此使用 UNPIVOT(我不确定古代 Oracle 10 是否已经支持该功能 - 我已经有十多年没有使用它了)
select colname, count(*) - count(val) as num_nulls
from t1
UNPIVOT include nulls
(val for colname in (col1 as 'C1',
col2 as 'C2',
col3 as 'C3'))
group by colname
order by colname;
不确定这是否更快。
在线示例:https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=4e807b8b2d8080abac36574f776dbf04
【讨论】:
谢谢,这正是我要找的。span> 但是当列的数据类型不同时会引起问题。【参考方案2】:Oracle 10g 不支持 UNPIVOT 和 PIVOT 运算符,因此要执行 10g 中的操作,您需要使用虚拟表(包含与未透视的列相同的行数 - 在您的情况下,也就是3),像这样:
WITH your_table AS (SELECT 1 col1, 0 col2, NULL col3 FROM dual UNION ALL
SELECT NULL col1, NULL col2, NULL col3 FROM dual UNION ALL
SELECT 3 col1, NULL col2, NULL col3 FROM dual UNION ALL
SELECT NULL col1, 5 col2, 1 col3 FROM dual)
SELECT CASE WHEN dummy.id = 1 THEN 'col1'
WHEN dummy.id = 2 THEN 'col2'
WHEN dummy.id = 3 THEN 'col3'
END column_name,
COUNT(CASE WHEN dummy.id = 1 THEN CASE WHEN col1 IS NULL THEN 1 END
WHEN dummy.id = 2 THEN CASE WHEN col2 IS NULL THEN 1 END
WHEN dummy.id = 3 THEN CASE WHEN col3 IS NULL THEN 1 END
END) null_count
FROM your_table
CROSS JOIN (SELECT LEVEL ID
FROM dual
CONNECT BY LEVEL <= 3) dummy
GROUP BY dummy.id;
COLUMN_NAME NULL_COUNT
----------- ----------
col1 2
col2 2
col3 3
如果您认为编写大量列需要很长时间,您始终可以编写一个自己生成大量案例语句的查询,例如:
SELECT 'when dummy.id = '||row_number() OVER (PARTITION BY owner, table_name ORDER BY column_id)||' then '''||LOWER(column_name)||'''' first_part,
'when dummy.id = '||row_number() OVER (PARTITION BY owner, table_name ORDER BY column_id)||' then case when '||column_name||' is null then 1 end' second_part
FROM all_tab_columns a
WHERE owner = ...
AND table_name = ...
-- and column_name in (...)
ORDER BY column_id;
(我包含了row_number()
分析函数而不是使用 column_id,因为如果您排除某些列,则 column_id 列将不再是从 1 开始的连续数字。)
【讨论】:
以上是关于如何计算每列中有多少个空值?的主要内容,如果未能解决你的问题,请参考以下文章
如何列出各个列,其中每个列包含一个 id 计数,其中每列中的 id 不在 MySQL 中每列的不同表中