【问题标题】:How to select columns from a table which have non null values?如何从具有非空值的表中选择列?
【发布时间】:2011-01-14 06:15:45
【问题描述】:

我有一个包含数百列的表,其中许多列是空的,我希望我的 select 语句只返回那些包含值的列。这将帮助我更好地分析数据。比如:

从表名中选择(非空列);

我想选择所有至少有一个非空值的列。

这个可以吗?

【问题讨论】:

  • 你的问题很不清楚。如所写,您似乎要求从表中选择 all 行?这真的是你所追求的吗?还是您的意思是包含 WHERE 子句并仅选择感兴趣的列中包含非 NULL 值的行?或者您是否要选择所有行不可为空的所有列?你能解释一下吗?
  • 我觉得这个问题很清楚。他只想选择至少有一行包含数据的列。当然,拥有 WHERE 子句会使这变得更加困难。
  • 您想如何处理这些数据?将在哪里使用?
  • "non null" 与 "not nullable" 的含义完全不同。您想要哪个 - 查看至少存在一个非空值的行,还是只查看具有“不可为空”约束的列?

标签: sql oracle select null


【解决方案1】:
select column_name
from user_tab_columns
where table_name='Table_name' and num_nulls=0;

这是获取非空列的简单代码..

【讨论】:

    【解决方案2】:

    使用下面的:

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

    Table_Name 必须相应替换...

    【讨论】:

    • 列可以为空,并不意味着其中没有数据。
    • 值得注意的是,information_schema 在 MySQL 中可用,但在 Oracle 数据库中不可用。这个问题是特定于 Oracle 数据库的。这可能会帮助那些正在寻找与 MySQL 相关的答案的人,但它与问题并不是特别相关。
    【解决方案3】:

    看看统计信息,它可能对你有用:

    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_COLUMNSALL_TABLES

    【讨论】:

      【解决方案4】:

      我认为这不能在单个查询中完成。您可能需要一些 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;
      

      【讨论】:

        【解决方案5】:
        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)
        

        【讨论】:

        • 请不要只写代码作为答案。解释它的作用和工作原理。
        【解决方案6】:

        您要求做的是在整个结果中建立对每一行的依赖关系。这实际上是永远你想要的。想想如果在一行中每一列的值都为“0”的后果——结果集的模式突然增长到包括所有那些以前“空”的列。您实际上以指数方式增加了 '*' 的坏处,现在您的结果集不仅仅依赖于表的元数据,而是整个结果集都依赖于普通数据。

        你要做的只是选择你想要的字段,不要偏离这个简单的计划。

        【讨论】:

        • 我想他们只是想在到处都是数百列 NULL 的海洋中看到相关的伪装数据。这将帮助他们最终构建具有特定字段的查询。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多