对所有具有 null 的列进行 unpivot

unpivot for all columns which is having null

我想要 table 中的所有列,每列中的空值计数都为空值。

我有类似

的查询
Select count(*)-count(COLA),count(*)-count(COLB),......count(*)-count(COLN) FROM TABLE;

我想计算从 table 行到列具有空值的每一列。

COLUMN NAME - COUNT
COLA        - 0
COLB        - 2
.
.
.
COLN        - 7

您可以按如下方式使用UNPIVOT

Select * from
(Select count(case when cola is null then 1 end) cola_cnt,
count(case when colb is null then 1 end) colb_cnt,
...
...
From your_table)
UNPIVOT
( CNT
  FOR col_name in
  (Cola_cnt, colb_cnt, ...)
);

演示:

示例数据的创建:

SQL> CREATE TABLE YOUR_TABLE (COLA NUMBER, COLB NUMBER);

Table created.

SQL> INSERT INTO YOUR_TABLE VALUES (1,NULL);

1 row created.

SQL> INSERT INTO YOUR_TABLE VALUES (NULL,2);

1 row created.

SQL> INSERT INTO YOUR_TABLE VALUES (3,NULL);

1 row created.

SQL> SELECT * FROM YOUR_TABLE;

      COLA       COLB
---------- ----------
         1
                    2
         3

查询查找所需数据:

SQL> SELECT * FROM
  2      (   SELECT
  3              COUNT(CASE
  4                  WHEN COLA IS NULL THEN 1
  5              END) COLA_CNT,
  6              COUNT(CASE
  7                  WHEN COLB IS NULL THEN 1
  8              END) COLB_CNT
  9          FROM YOUR_TABLE
 10      ) UNPIVOT ( CNT
 11          FOR COL_NAME
 12      IN ( COLA_CNT,
 13           COLB_CNT ) );

COL_NAME        CNT
-------- ----------
COLA_CNT          1
COLB_CNT          2

SQL>

干杯!!

可以这样写:

Select * from
(
 Select count(*)-count(COLA) Cola_cnt,count(*)-count(COLB) colb_cnt,......count(*)-count(COLN)
From your_table
)
UNPIVOT
( YOUR_COUNT
  FOR col_name in
  (Cola_cnt, colb_cnt, ...)
);

如果您希望输出中的行按特定顺序排列,则必须在 UNPIVOT 操作中包含该顺序。这可以使用 UNPIVOT 运算符或 "the old way"(在 Oracle 引入 UNPIVOT 运算符之前如何完成逆透视)来完成,如下所示。

考虑 SCOTT 架构中的标准 EMP table。它有几列。假设我们想要按顺序在 EMPNO、ENAME、MGR 和 COMM 列中显示空计数。如果您检查 table,您会看到它有 14 行。 EMPNO 是主键,因此该列中没有空值。 ENAME 不是 NULL,因此显然该列中也没有空值。 MGR 恰好有一个空值(只有一个人没有经理:公司总裁)。 COMM 有很多空值(准确地说是 10 个)。

以下是编写查询的方法:

select h.col, 
       sum(case h.col when 'EMPNO' then nvl2(e.empno, 0, 1)
                      when 'ENAME' then nvl2(e.ename, 0, 1)
                      when 'MGR'   then nvl2(e.mgr  , 0, 1)
                      when 'COMM'  then nvl2(e.comm , 0, 1)  end) as null_count
from   scott.emp e cross join 
       (select 'EMPNO' as col, 1 as ord from dual union all
        select 'ENAME'       , 2        from dual union all
        select 'MGR'         , 3        from dual union all
        select 'COMM'        , 4        from dual          ) h
group  by h.col, h.ord
order  by h.ord
;

COL   NULL_COUNT
----- ----------
EMPNO          0
ENAME          0
MGR            1
COMM          10

严格来说,我标记为 h 的硬编码辅助子查询可能只有 ORD 列(然后在 SELECT 子句),但我发现这个更冗长的变体更容易理解。