我有一个非常大的Oracle表,其中包含许多与我使用的每个过滤器无关的列。
我想在Oracle中编写一个查询或函数,它返回仅具有空值的列的名称,或者返回非空的列的名称。
答案 0 :(得分:3)
如果您只想查找始终为null的列,则可以运行此查询创建的查询,那些值为0的列为null。
select 'select '
|| listagg('count(' || column_name || ') as ' || column_name, ', ')
within group (order by column_id)
|| ' from my_table;'
from user_tab_columns
where table_name = 'MY_TABLE'
这是一个SQL Fiddle来演示。
如果您想要列的名称,则必须使用PL / SQL。此函数将返回以逗号分隔的列名列表,但当然您可以返回用户定义的类型等。
create or replace function null_cols( P_TableName varchar2 ) return varchar2 is
l_cols varchar2(32767);
l_result number;
begin
for i in ( select column_name
from user_tab_columns
where table_name = upper(P_TableName)
) loop
execute immediate 'select count(' || i.column_name || ')
from ' || P_TableName
into l_result;
if l_result = 0 then
l_cols := l_cols || i.column_name || ', ';
end if;
end loop;
return l_cols;
end;
/
这是添加了该功能的同一SQL Fiddle的扩展名。
我必须补充一点,如果您为了使用该函数而接受用户输入,则应使用dbms_assert
包以避免SQL注入。
答案 1 :(得分:0)
您可以使用以下查询来识别相同的内容,请确保收集统计信息以获得正确的结果
select table_name, column_name
from user_tab_cols
where table_name = 'MY_TABLE'
and NUM_DISTINCT = 0
and NUM_NULLS > 0
更新1: - 如果您定期收集统计数据(不是100%统计数据),您可以使用Ben的答案并进行优化。以下将减少需要检查的列数
for i in ( select column_name
from user_tab_columns
where table_name = upper(P_TableName)
and num_distinct=0 and num_nulls > 0
) loop