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

Sql 如何计算每列中有多少空值?,sql,oracle,oracle10g,Sql,Oracle,Oracle10g,我有一张这样的桌子: col1col2col3 10null nullnullnull 3nullnull null51 我希望在Oracle 10G中有这样的输出: 列名称空计数 col12 col22 col33 我使用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 a

我有一张这样的桌子:

col1
col2
col3

1
0
null

null
null
null

3
null
null

null
5
1

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

列名称
空计数

col1
2

col2
2

col3
3

我使用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的情况下实现这一点


你可以使用UNPIVOT(我不确定古代甲骨文10是否已经支持了这一点——我已经十多年没有使用过了)

但不确定这是否更快


联机示例:

Oracle 10g不支持取消PIVOT和PIVOT运算符,因此要在10g中执行您所追求的操作,您需要使用一个虚拟表(包含与取消PIVOT的列相同的行数-在您的示例中,为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

(我使用了
行编号()
分析函数,而不是使用列id,因为如果排除某些列,列id列将不再是从1开始的连续数字。)

谢谢,这正是我要查找的。但当列的数据类型不同时,这会导致问题。
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;