2010-02-08 17 views
20

Ho una tabella contenente centinaia di colonne molte delle quali sono null e vorrei avere la mia istruzione select in modo che vengano restituite solo le colonne contenenti un valore. Mi aiuterebbe ad analizzare meglio i dati. Qualcosa del tipo:Come selezionare le colonne da una tabella che hanno valori non nulli?

Selezionare (colonne non nulle) da tablename;

Desidero selezionare tutte le colonne che hanno almeno un valore non nullo.

Questo può essere fatto?

+0

La tua domanda è abbastanza poco chiaro. Come scritto, sembra che tu stia chiedendo di SELEZIONARE * tutte * le righe da un tavolo? E 'davvero quello che cerchi? O intendi includere una clausola WHERE e SELEZIONA solo le righe che contengono valori non NULL nelle colonne di interesse? O vuoi selezionare tutte le colonne che non sono nulle per tutte le righe? Potresti spiegarlo per favore? –

+5

Trovo la domanda abbastanza chiara. Vuole selezionare solo le colonne per le quali almeno una riga contiene dati. Avere una clausola WHERE renderebbe questo ancora più difficile, ovviamente. – Thilo

+0

cosa ti piacerebbe fare con i dati? dove sarà usato? – shahkalpesh

risposta

3

Date un'occhiata come le informazioni statistiche, può essere utile per voi:

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. 

Per esempio è possibile verificare se NUM_NULLS = NUM_ROWS per identificare le colonne "vuoti".
Riferimento: ALL_TAB_COLUMNS, ALL_TABLES.

2

Non penso che questo possa essere fatto in una singola query. Potresti aver bisogno di un plsql per testare prima quali colonne contengono dati e mettere insieme una dichiarazione basata su tali informazioni. Ovviamente, se i dati nella tua tabella cambiano devi ricreare la dichiarazione.

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; 
-1

Quello che stai chiedendo di fare è stabilire una dipendenza su ogni riga nell'intero risultato. Questo è infatti non sempre quello che vuoi. Basti pensare alle ramificazioni se in una riga ogni colonna avesse il valore '0' - improvvisamente lo schema del set di risultati cresce per includere tutte quelle colonne precedentemente "vuote". Stai aumentando in modo esponenziale la cattiveria di "*", ora il set di risultati non dipende solo dai metadati della tabella, ma l'intero set di risultati dipende dai dati semplici.

Quello che vuoi fare è selezionare i campi che hanno quello che vuoi, e non deviare da questo semplice piano.

4
select column_name 
from user_tab_columns 
where table_name='Table_name' and num_nulls=0; 

Ecco il codice semplice per ottenere le colonne non nulli ..

0
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) 
+1

Si prega di non scrivere semplicemente il codice come risposta. Spiega cosa fa e come funziona. –

2

Usare la sottostante:

SELECT * 
FROM information_schema.columns 
WHERE table_name = 'Table_Name' and is_nullable = 'NO' 

Table_Name deve essere sostituito di conseguenza ...

+1

SQL 2012 funziona perfettamente! – Raffaeu

+0

Solo perché una colonna è annullabile, non significa che non avrà dati in essa. – Seth

Problemi correlati