选择条目不为null的列名

时间:2012-11-15 14:55:14

标签: mysql select null

我希望有一个表的列表,其中至少有一个非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条目的列?

2 个答案:

答案 0 :(得分:10)

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上查看。

答案 1 :(得分:0)

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

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;