J'ai une table contenant des centaines de colonnes, dont beaucoup sont nulles, et j'aimerais que ma requête select soit retournée. Cela m'aiderait à mieux analyser les données. Quelque chose comme:
Sélectionnez (colonnes non nulles) à partir de nom_table;
Je veux sélectionner toutes les colonnes qui ont au moins une valeur non nulle.
Cela peut-il être fait?
Regardez comme informations statistiques, cela peut vous être utile:
SQL> exec dbms_stats.gather_table_stats('SCOTT','EMP');
PL/SQL procedure successfully completed.
SQL> select num_rows from all_tables where owner='SCOTT' and table_name='EMP';
NUM_ROWS
----------
14
SQL> select column_name,nullable,num_distinct,num_nulls from all_tab_columns
2 where owner='SCOTT' and table_name='EMP' order by column_id;
COLUMN_NAME N NUM_DISTINCT NUM_NULLS
------------------------------ - ------------ ----------
EMPNO N 14 0
ENAME Y 14 0
JOB Y 5 0
MGR Y 6 1
HIREDATE Y 13 0
SAL Y 12 0
COMM Y 4 10
DEPTNO Y 3 0
8 rows selected.
Par exemple, vous pouvez vérifier si NUM_NULLS = NUM_ROWS identifie les colonnes "vides".
Référence: ALL_TAB_COLUMNS , ALL_TABLES .
select column_name
from user_tab_columns
where table_name='Table_name' and num_nulls=0;
Voici un code simple pour obtenir des colonnes non NULL.
Je ne pense pas que cela puisse être fait en une seule requête. Vous aurez peut-être besoin de certains plsql pour tester d’abord les colonnes contenant des données et assembler une déclaration basée sur ces informations. Bien sûr, si les données de votre table changent, vous devez recréer l'instruction.
declare
l_table varchar2(30) := 'YOUR_TABLE';
l_statement varchar2(32767);
l_test_statement varchar2(32767);
l_contains_value pls_integer;
-- select column_names from your table
cursor c is
select column_name
,nullable
from user_tab_columns
where table_name = l_table;
begin
l_statement := 'select ';
for r in c
loop
-- If column is not nullable it will always contain a value
if r.nullable = 'N'
then
-- add column to select list.
l_statement := l_statement || r.column_name || ',';
else
-- check if there is a row that has a value for this column
begin
l_test_statement := 'select 1 from dual where exists (select 1 from ' || l_table || ' where ' ||
r.column_name || ' is not null)';
dbms_output.put_line(l_test_statement);
execute immediate l_test_statement
into l_contains_value;
-- Yes, add column to select list
l_statement := l_statement || r.column_name || ',';
exception
when no_data_found then
null;
end;
end if;
end loop;
-- create a select statement
l_statement := substr(l_statement, 1, length(l_statement) - 1) || ' from ' || l_table;
end;
Utilisez le ci-dessous:
SELECT *
FROM information_schema.columns
WHERE table_name = 'Table_Name' and is_nullable = 'NO'
Table_Name
doit être remplacé en conséquence ...
select rtrim (xmlagg (xmlelement (e, column_name || ',')).extract ('//text()'), ',') col
from (select column_name
from user_tab_columns
where table_name='<table_name>' and low_value is not null)