对所有具有 null 的列进行取消透视

Posted

技术标签:

【中文标题】对所有具有 null 的列进行取消透视【英文标题】:unpivot for all columns which is having null 【发布时间】:2019-11-12 04:50:58 【问题描述】:

我希望表中的所有列都具有空值计数,每列中的空值计数为空。

我有类似的查询

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

我想计算表中每一列在行到列中都有空值的计数。

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

【问题讨论】:

【参考方案1】:

你可以这样写:

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, ...)
);

【讨论】:

【参考方案2】:

您可以使用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>

干杯!!

【讨论】:

【参考方案3】:

如果您希望输出中的行按特定顺序排列,则必须在 UNPIVOT 操作中包含该顺序。这可以通过 UNPIVOT 操作符或“旧方法”(在 Oracle 引入 UNPIVOT 操作符之前如何进行反透视)来完成,如下所示。

考虑 SCOTT 架构中的标准 EMP 表。它有几列。假设我们要按顺序在列 EMPNO、ENAME、MGR 和 COMM 中显示空计数。如果您检查该表,您将看到它有 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 子句的 CASE 表达式中使用相应的数字而不是列名),但我发现这个更详细的变体更容易理解。

【讨论】:

以上是关于对所有具有 null 的列进行取消透视的主要内容,如果未能解决你的问题,请参考以下文章

使用 column_name 函数取消透视表

如何根据条件行值对 pandas 数据框进行取消堆叠或取消透视?

尝试在 Oracle SQL 中取消透视列时出错

反透视具有多列的数据 - 请语法帮助

当整列为 0 或 null 时,有没有办法可以隐藏 Oracle View 数据透视表中的列?

Sql Server:如何使用别名取消透视?