如何计算每列中有多少个空值?

Posted

技术标签:

【中文标题】如何计算每列中有多少个空值?【英文标题】:How to calculate how many null values are present in each column? 【发布时间】:2019-04-30 14:03:51 【问题描述】:

我有一张这样的桌子:

col1col2col3 1 0nullnull nullnull 3nullnullnull 5 1

我希望在 Oracle 10G 中得到这样的输出:

column_namenull_countcol1 2col2 2col3 @ 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 开始的连续数字。)

【讨论】:

以上是关于如何计算每列中有多少个空值?的主要内容,如果未能解决你的问题,请参考以下文章

用 pentaho 计算每列空值的数量

如何计算Oracle SQL中从右侧开始的列中有多少个零

如何计算每列中唯一的重复值

如何列出各个列,其中每个列包含一个 id 计数,其中每列中的 id 不在 MySQL 中每列的不同表中

在python中,我如何对一列中每个值与另一列中的值发生的次数(多少行)建立矩阵?

Python - 每列中所选行的标准偏差