У меня есть таблица, содержащая сотни столбцов, многие из которых являются пустыми, и я хотел бы, имеют мой избранный оператор так, чтобы только те столбцы, содержащие значение, были возвращены. Это помогло бы мне проанализировать данные лучше. Что-то как:
Выберите (не пустые столбцы) от имени таблицы;
Я хочу выбрать все столбцы, которые имеют по крайней мере одно ненулевое значение.
Это может быть сделано?
Посмотрите статистическую информацию, она может быть вам полезна:
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.
Например, вы можете проверить, если NUM_NULLS = NUM_ROWS для определения «пустых» столбцов.
Ссылка: ALL_TAB_COLUMNS , ALL_TABLES .
Что вы просите сделать устанавливает зависимость для каждой строки всего результата. На самом деле это никогда не то, что вам нужно. Только подумайте о последствиях, если бы в одной строке каждый столбец имел значение «0» - внезапно схема вашего набора результатов вырастет, чтобы включить все эти ранее «пустые» столбцы. Вы эффективно увеличиваете вредность '*' в геометрической прогрессии, теперь ваш набор результатов не зависит только от метаданных таблицы - но весь ваш набор результатов зависит от простых данных.
Вам нужно просто выбрать поля, в которых есть то, что вам нужно, и не отклоняться от этого простого плана.
Я не думаю, что это можно сделать с помощью одного запроса. Вам может потребоваться некоторый plsql, чтобы сначала проверить, какие столбцы содержат данные, и составить оператор на основе этой информации. Конечно, если данные в вашей таблице изменятся, вам придется воссоздать инструкцию.
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;