如何找到哪个列为空?

时间:2015-11-09 11:33:01

标签: sql oracle select

SELECT ....
FROM   table_name
WHERE  a_column is null
OR     b_column is null
OR     c_column is null
......;

这是我的SQL查询。我拿了SELECT结果,但我不知道哪个列是空的,我拿了这个结果。但是我的表名和列名是动态的。我可以用EXECUTE IMMEDIATE编译。我需要找到空列,然后我应该使用这些信息。你能救我吗?

4 个答案:

答案 0 :(得分:2)

找出所有完全具有NULL值的列的另一种方法是,您可以查询 [DBA | ALL | USER] _TAB_COLUMNS 视图并检查NUM_DISTINCT = 0

注意:必须及时收集统计信息才能获得准确的结果。

例如,

假设我有桌子" T "它有两列,EMPNOSALSAL列完全 NULL

SQL> SELECT * FROM LALIT.t;

     EMPNO        SAL
---------- ----------
      7369
      7499
      7521
      7566
      7654
      7698
      7782
      7788
      7839
      7844
      7876
      7900
      7902
      7934

14 rows selected.

让安全方收集统计信息

SQL> BEGIN
  2    DBMS_STATS.gather_table_stats(
  3      'LALIT',
  4      'T');
  5  END;
  6  /

PL/SQL procedure successfully completed.

所需的输出

SQL> SELECT column_name,
  2    num_distinct
  3  FROM user_tab_columns
  4  WHERE NUM_DISTINCT = 0
  5  AND table_name     ='T';

COLUMN_NAME NUM_DISTINCT
----------- ------------
SAL                    0

因此,您获得的列完全为NULL,即 num_distinct 0

更新根据OP的评论,它可能至少是一个NULL值。

  • 您可以查询NUM_NULLS <> 0
  • 的相同视图

例如,在SCOTT架构的标准 EMP 表中,让我们查找至少一个NULL值的列。

SQL> SELECT column_name,
  2         num_nulls
  3  FROM user_tab_columns
  4  WHERE NUM_NULLS <> 0
  5  AND table_name     ='EMP';

COLUMN_NAME  NUM_NULLS
----------- ----------
COMM                11
MGR                  1

请记住,必须及时收集统计数据。

  • PL / SQL 中使用 EXECUTE IMMEDIATE 的另一种方式:

只需撤消有关Find all columns having at least a NULL value from all tables in the schema的演示中的NULL逻辑。

例如,

FIND_NULL_COL 是一个简单的用户定义函数(UDF),对于至少有一个 {{1}的列,它将返回1 } 值:

NULL

调用 SQL 中的函数以获取任何表的所有列的NULL状态:

SQL> CREATE OR REPLACE FUNCTION FIND_NULL_COL(
  2      TABLE_NAME  VARCHAR2,
  3      COLUMN_NAME VARCHAR2)
  4    RETURN NUMBER
  5  IS
  6    cnt NUMBER;
  7  BEGIN
  8    CNT :=1;
  9    EXECUTE IMMEDIATE 'select count(*) from ' ||TABLE_NAME||' where '
 10                                              ||COLUMN_NAME||' is null'
 11    INTO cnt;
 12    RETURN
 13    CASE
 14    WHEN CNT > 0 THEN
 15      1
 16    ELSE
 17      0
 18    END;
 19  END;
 20  /

Function created.

因此, NULL_STATUS SQL> SELECT c.TABLE_NAME, 2 c.COLUMN_NAME, 3 FIND_NULL_COL(c.TABLE_NAME,c.COLUMN_NAME) null_status 4 FROM all_tab_columns c 5 WHERE C.OWNER ='SCOTT' 6 AND c.TABLE_NAME = 'EMP' 7 ORDER BY C.OWNER, 8 C.TABLE_NAME, 9 C.COLUMN_ID 10 / TABLE_NAME COLUMN_NAME NULL_STATUS ---------- ----------- ----------- EMP EMPNO 0 EMP ENAME 0 EMP JOB 0 EMP MGR 1 EMP HIREDATE 0 EMP SAL 0 EMP COMM 1 EMP DEPTNO 0 8 rows selected. 是至少有一个 NULL 值的列。

答案 1 :(得分:1)

在select子句中使用case并输出空列名称,如下所示。

select case when o1+o2+o3 = 7 then 'a_column,b_column,c_column'
when o1+o2+o3 = 6 then 'b_column,c_column'
when o1+o2+o3 = 5 then 'a_column,c_column'
when o1+o2+o3 = 4 then 'c_column'
when o1+o2+o3 = 3 then 'a_column,b_column'
when o1+o2+o3 = 2 then 'b_column'
when o1+o2+o3 = 1 then 'a_column'
else 'none'
end as nullColumns, l.*
from (
SELECT 
case when a_column is null then 1 end as o1,
case when b_column is null then 2 end as o2,
case when c_column is null then 4 end as o3,
t.*
FROM table_name t WHERE a_column is null OR b_column is null OR c_column is null) l

答案 2 :(得分:1)

使用CASE WHEN

select 
  case when a_column is null then 1 else 0 end as a_col_null,
  case when b_column is null then 1 else 0 end as b_col_null,
  case when c_column is null then 1 else 0 end as c_col_null,
  ......
from table_name 
where a_column is null 
or b_column is null 
or c_column is null ...... ;

1表示“是”,0表示“否”。你也可以使用字符串,例如'Y'/'N'或'TRUE'/'FALSE'或您喜欢的任何内容。 (只有你不能使用BOOLEAN,因为Oracle缺乏BOOLEAN数据类型。)

您尚未编辑您的请求。您还没有添加示例。你还没有回答过Gordon Linoff和Utsav的问题。你应该学会在这里提问。

到目前为止,我从信息中收集到的是,您不希望查找列为空的记录(这是您对查询执行的操作)。您想知道所有记录的列是否为空。

下面的查询为您提供表中avery行为空的所有列的列名。因此,当一切正常或者你得到一个或多个列名

时,你要么得到一个空字符串
select 
  trim(',' from regexp_replace(
    case when count(a_column) = 0 then 'a_column' end || ',' ||
    case when count(b_column) = 0 then 'b_column' end || ',' ||
    ......
  , ',+', ',')) as columns
from table_name;

答案 3 :(得分:1)

如果要构建表中包含至少一个值的列的列表,可以执行以下操作:

select stuff((case when count(a_column) > 0 then ', a_column' else '' end) +
             (case when count(a_column) > 0 then ', b_column' else '' end) +
             (case when count(a_column) > 0 then ', c_column' else '' end) +
             . . ., 
             1, 2, '') as ColumnsWithValues            
from t;