【问题标题】:Select column names whose entries are not null选择条目不为空的列名
【发布时间】:2014-03-29 04:40:46
【问题描述】:

我想要一个表中至少包含一个非NULL 数据条目的列的列表。

换句话说,我想获取以下至少返回一个条目的列名:

SELECT DISTINCT column_name FROM table WHERE column_name IS NOT NULL

我尝试了以下方法:

SELECT column_name
FROM information_schema.columns
WHERE table_name = "table_name"
AND EXISTS (
    SELECT DISTINCT column_name FROM table_name WHERE column_name IS NOT NULL
)

但这也会返回所有条目都是NULL的列名。

那么我如何只获取那些具有非NULL 条目的列?

【问题讨论】:

    标签: mysql select null


    【解决方案1】:

    INFORMATION_SCHEMA.COLUMNS 表中创建一个包含您要执行的SQL 的字符串,然后从该字符串中创建prepare a statement 并执行它。

    我们希望构建的 SQL 如下所示:

      SELECT 'column_a'
      FROM   table_name
      WHERE `column_a` IS NOT NULL
      HAVING COUNT(*)
    UNION ALL
      SELECT 'column_b'
      FROM   table_name
      WHERE `column_b` IS NOT NULL
      HAVING COUNT(*)
    -- etc.
    

    (可以省略WHERE 子句并用COUNT(*) 替换COUNT(column),但我认为在索引列上可能效率较低)。

    这可以通过以下方式完成:

    SET group_concat_max_len = 4294967295;
    
    SELECT GROUP_CONCAT(
     ' SELECT ',QUOTE(COLUMN_NAME),
     ' FROM   table_name',
     ' WHERE `',REPLACE(COLUMN_NAME, '`', '``'),'` IS NOT NULL',
     ' HAVING COUNT(*)'
    SEPARATOR ' UNION ALL ')
    INTO   @sql
    FROM   INFORMATION_SCHEMA.COLUMNS
    WHERE  TABLE_SCHEMA = DATABASE()
       AND TABLE_NAME = 'table_name';
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    

    sqlfiddle 上查看。

    【讨论】:

    • 对不起...在 iPad 上查看并认为它已注册...绝对值得一票:)
    【解决方案2】:

    使用此过程,这将打印至少有一个非空行的表的列名。

    create or replace procedure list_col_notNull(tblName in varchar2)
    as
    lv_col_name varchar2(200);
    lv_ctr number;
    lv_sql varchar2(400);
    CURSOR cur_col_name is
    SELECT column_name
    FROM USER_TAB_COLUMNS U
    WHERE table_name = tblName order by column_name asc;
    begin
    open cur_col_name;
    
    LOOP
        FETCH cur_col_name INTO lv_col_name; 
        EXIT WHEN cur_col_name%NOTFOUND; 
        lv_sql := 'select count(1) From ' || tblName || ' where ' || lv_col_name || ' is not null'  ;  
        EXECUTE IMMEDIATE lv_sql into lv_ctr;
        if lv_ctr > 0
        then
            dbms_output.put_line(lv_col_name);
        end if;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      相关资源
      最近更新 更多