2010-02-08 4 views
20

Ich habe eine Tabelle mit Hunderten von Spalten, von denen viele Null sind, und ich möchte meine Select-Anweisung, so dass nur die Spalten zurückgegeben werden, die einen Wert enthalten. Es würde mir helfen, Daten besser zu analysieren. So etwas wie:Wie wählt man Spalten aus einer Tabelle, die nicht Nullwerte haben?

Wählen Sie (nicht Null Spalten) aus Tabellenname;

Ich möchte alle Spalten auswählen, die mindestens einen Wert ungleich Null haben.

Kann dies getan werden?

+0

Ihre Frage ersetzt ist ziemlich unklar. Wie geschrieben, sieht es so aus, als würden Sie * ALLE * Zeilen aus einer Tabelle AUSWÄHLEN? Ist das wirklich was du willst? Oder wollen Sie eine WHERE-Klausel einschließen und nur die Zeilen auswählen, die in den interessierenden Spalten Nicht-Null-Werte enthalten? Oder möchten Sie alle Spalten auswählen, die für alle Zeilen nicht nullbar sind? Könnten Sie bitte erläutern? –

+5

Ich finde die Frage ziemlich klar. Er möchte nur die Spalten auswählen, für die mindestens eine Zeile Daten enthält. Eine WHERE-Klausel würde das natürlich noch schwieriger machen. – Thilo

+0

Was möchten Sie mit den Daten machen? Wo wird es verwendet werden? – shahkalpesh

Antwort

3

Werfen Sie einen Blick, wie Statistikinformationen, es für Sie nützlich sein können:

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. 

Zum Beispiel Sie, wenn NUM_NULLS = NUM_ROWS überprüfen „leer“ Spalten zu identifizieren.
Referenz: ALL_TAB_COLUMNS, ALL_TABLES.

2

Ich glaube nicht, dass dies in einer einzigen Abfrage durchgeführt werden kann. Möglicherweise benötigen Sie einige plsql, um zuerst zu testen, welche Spalten Daten enthalten, und eine Anweisung basierend auf diesen Informationen zu erstellen. Wenn sich die Daten in Ihrer Tabelle ändern, müssen Sie natürlich die Anweisung neu erstellen.

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

Sie möchten eine Abhängigkeit von jeder Zeile im gesamten Ergebnis festlegen. Dies ist in der Tat nicht immer was Sie wollen. Denken Sie nur an die Verzweigungen, wenn jede Spalte in einer Zeile den Wert "0" hat - plötzlich wächst das Schema Ihrer Ergebnismenge auf alle zuvor "leeren" Spalten. Sie erhöhen effektiv die Schlechtigkeit von '*' exponentiell, jetzt hängt Ihre Ergebnismenge nicht nur von den Metadaten der Tabelle ab - sondern Ihre gesamte Ergebnismenge hängt von den reinen Daten ab.

Was Sie tun möchten, ist nur die Felder auszuwählen, die haben, was Sie wollen, und nicht von diesem einfachen Plan abweichen.

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

ist hier einfacher Code ..

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

Bitte schreibe nicht einfach Code als Antwort. Erkläre, was es macht und wie es funktioniert. –

2

Verwenden Sie die unten nicht null-Spalten zu erhalten:

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

Table_Name werden muss, entsprechend ...

+1

SQL 2012 funktioniert perfekt! – Raffaeu

+0

Nur weil eine Spalte nullfähig ist, heißt das nicht, dass sie keine Daten enthält. – Seth