我有一个这样的表A:
col1
col2
{{1 }}
col3
1
0
null
null
null
null
3
null
null
null
5
我想要在 Oracle 10G 中输出如下内容:
1
column_name
null_count
col1
2
col2
2
col3
我已经使用 UNION ALL 做到了这一点:
3
工作正常,但要花很多时间,因为有近100个 UNION ALL 。我想在不使用 UNION ALL 的情况下实现相同的输出。
是否可以通过不使用 UNION ALL 来实现这一目标?
答案 0 :(得分: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
答案 1 :(得分:0)
我会推荐此查询:
SELECT 'col1' AS col_name, COUNT(*) - COUNT(col1) AS col_null_count FROM t UNION ALL
SELECT 'col2' AS col_name, COUNT(*) - COUNT(col2) AS col_null_count FROM t UNION ALL
SELECT 'col3' AS col_name, COUNT(*) - COUNT(col3) AS col_null_count FROM t
但是您可以尝试这样写:
WITH cte AS (
-- 1 rows by n columns
SELECT COUNT(*) - COUNT(col1) AS col1_null_count
, COUNT(*) - COUNT(col2) AS col2_null_count
, COUNT(*) - COUNT(col3) AS col3_null_count
FROM t
)
-- n rows by 2 columns
SELECT 'col1' AS col_name, col1_null_count AS col_null_count FROM cte UNION ALL
SELECT 'col2' AS col_name, col2_null_count AS col_null_count FROM cte UNION ALL
SELECT 'col3' AS col_name, col3_null_count AS col_null_count FROM cte
答案 2 :(得分:0)
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
如果您认为写大量列会花费很多时间,则始终可以编写一个查询,该查询将自己生成大量case语句,例如:
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开始的连续数字。)