我必须编写一个非常有趣的查询,它使用值计算空值和行

时间:2014-10-31 07:31:11

标签: sql oracle oracle11g

我有一个场景,我需要计算每个ID的总值数和空值数 每个ID列都有多行

总结数据

- ID     Col1     Col2    Col3    Col4    Col5    Col6
 - 132    12       0.5      0      Null     0.3     1.5
 - 132    Null     0.5      0      Null     0.3     1.5
 - 132    1        0.5      Null   Null     0.3     1.5
 - 132    2        0.5      0      0.3      1.5     Null  
 - 132    21       0.5      0      Null     0.3     1.5

 - 133    Null     Null     0      Null     Null    1.5
 - 133    12       0.5      0      Null     0.3     1.5
 - 133    Null     0.5      0      Null     0.3     1.5
 - 133    1        0.5      Null   Null     0.3     1.5
 - 133    2        0.5      0      0.3      1.5     Null  
 - 133    1        Null     0      Null     0.3     1.5
 - 133    Null     Null     0      Null     0.3     1.5

总结答案:我需要编写一个查询,为我提供如下数据

- ID      NullCount    ValuesCount
 - 132      7               21    
 - 133      15              27    

我有一个部署快速帮助将非常感谢。

由于

6 个答案:

答案 0 :(得分:3)

改编自Oracle: How to count null and non-null rows

SELECT
  COUNT(Col1)+COUNT(Col2)+COUNT(Col3)+
  COUNT(Col4)+COUNT(Col5)+COUNT(Col6) AS ValuesCount,

  6*COUNT(*)-COUNT(Col1)-COUNT(Col2)-COUNT(Col3)-
  COUNT(Col4)-COUNT(Col5)-COUNT(Col6) AS NullCount
FROM data
GROUP BY id

COUNT(ColX)仅计算NOT NULL个值。当然,为所有六列添加等于ValuesCount COUNT(*)计算所有行,即使一行中的所有列都为NULL。将单元格总数乘以6,然后减去所有NOT NULL值以获得NULL计数。

答案 1 :(得分:2)

COUNT计算非空值。所以ValueCount很简单 - 添加每列的计数。

对于NullCount,您可以使用CASE或其他类似逻辑。或者您可以使用NVL2函数将任何NOT NULL转换为NULL,将任何NULL转换为NOT NULL(如常量)。

select id
     , count(nvl2(col1,null,1)) + count(nvl2(col2,null,1)) +
       count(nvl2(col3,null,1)) + count(nvl2(col4,null,1)) +
       count(nvl2(col5,null,1)) + count(nvl2(col6,null,1)) nullcount
     , count(col1) + count(col2) + count(col3) +
       count(col4) + count(col5) + count(col6) valuecount
  from tab
 group by id
 order by id
/

编辑:

另一种方法是 UNPIVOT 数据(可以使用UNPIVOT或其他非透视方法完成。)

select id
     , count(nvl2(col_value,null,1)) nullcount
     , count(col_value) valuecount
  from tab
 unpivot include nulls(
   col_value for col_name in (
      col1 as 'col1'
    , col2 as 'col2'
    , col3 as 'col3'
    , col4 as 'col4'
    , col5 as 'col5'
    , col6 as 'col6'
   )
 )
 group by id
 order by id
/

但是如果你有一个固定数量的列,那么在你只能通过执行一些复制粘贴来指定像我这样的所有列的单GROUP BY操作中获得所需结果时,进行非透视可能会有点过分。第一个例子。

答案 2 :(得分:0)

- 数据

SQL> WITH DATA AS(
  2    SELECT 132 ID,  12  Col1,0.5  Col2,0  Col3,NULL Col4,0.3 Col5,1.5 Col6 FROM dual UNION ALL
  3    SELECT 132 ,   NULL ,    0.5  ,    0   ,   NULL  ,   0.3  ,   1.5 FROM dual UNION ALL
  4    SELECT 132 ,   1   ,     0.5  ,    NULL,   NULL ,    0.3 ,   1.5 FROM dual UNION ALL
  5    SELECT 132 ,   2  ,      0.5  ,    0 ,     0.3  ,    1.5 ,    NULL   FROM dual UNION ALL
  6    SELECT 132 ,   21 ,      0.5  ,    0  ,    NULL ,    0.3 ,    1.5 FROM dual UNION ALL
  7    SELECT 133 ,   NULL ,    NULL ,    0  ,    NULL ,    NULL ,   1.5 FROM dual UNION ALL
  8    SELECT 133 ,   12  ,     0.5  ,    0  ,    NULL ,    0.3 ,    1.5 FROM dual UNION ALL
  9    SELECT 133 ,   NULL ,    0.5  ,    0  ,    NULL ,    0.3  ,   1.5 FROM dual UNION ALL
 10    SELECT 133 ,   1  ,      0.5 ,     NULL,   NULL ,    0.3  ,   1.5 FROM dual UNION ALL
 11    SELECT 133 ,   2  ,      0.5  ,    0  ,    0.3   ,   1.5 ,    NULL   FROM dual UNION ALL
 12    SELECT 133 ,   1  ,      NULL ,    0 ,     NULL  ,   0.3 ,    1.5 FROM dual UNION ALL
 13    SELECT 133 ,   NULL  ,   NULL ,    0 ,     NULL  ,   0.3  ,   1.5 FROM dual
 14    )

- 查询

 15    SELECT ID, sum(cnt) as nullcount from(
 16    SELECT ID, count(*) cnt FROM DATA
 17    WHERE col1 IS NULL
 18    GROUP BY ID
 19    UNION ALL
 20    SELECT ID, count(*) FROM DATA
 21    WHERE col2 IS NULL
 22    GROUP BY ID
 23    UNION ALL
 24    SELECT ID, count(*) FROM DATA
 25    WHERE col3 IS NULL
 26    GROUP BY ID
 27    UNION ALL
 28    SELECT ID, count(*) FROM DATA
 29    WHERE col4 IS NULL
 30    GROUP BY ID
 31    UNION ALL
 32    SELECT ID, count(*) FROM DATA
 33    WHERE col5 IS NULL
 34    GROUP BY ID
 35    UNION ALL
 36    SELECT ID, count(*) FROM DATA
 37    WHERE col6 IS NULL
 38    GROUP BY ID
 39  )
 40  GROUP BY ID
 41  /

                  ID            NULLCOUNT
-------------------- --------------------
                 132                    7
                 133                   15

SQL>

同样对于valuescount,请写一个in-line view

答案 3 :(得分:0)

select id, 6 * cnt_all - cnt_not_null, cnt_not_null from (
  select id, count(*) cnt_all, 
             count(col1)+count(col2)+count(col3)+count(col4)+count(col5)+count(col6) cnt_not_null
  from tab group by id
);

6是多列

COUNT(col)不考虑NULL值

COUNT(*)计算列中的所有值,包括NULLS

答案 4 :(得分:0)

select id, 
       (count(*) * 6) - (count(Col1) + count(Col2) + count(Col3) + count(Col4)+count(Col5)+count(Col6)) as NullCount, 
       count(Col1) + count(Col2) + count(Col3) + count(Col4)+count(Col5)+count(Col6) ValuesCount from 
       DATA 
group by id 
order by id;

答案 5 :(得分:-1)

一个可怕但有效的版本:

select distinct N.ID, 
(select count(*) from tab N2 where N2.ID = N.ID and col1 is null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col2 is null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col3 is null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col4 is null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col5 is null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col6 is null) 'Null'
, 
(select count(*) from tab N2 where N2.ID = N.ID and col1 is not null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col2 is not null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col3 is not null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col4 is not null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col5 is not null)
+ (select count(*) from tab N2 where N2.ID = N.ID and col6 is not null) 'Not null'
from tab N