计算数据透视中的NULL

时间:2019-01-24 18:00:19

标签: sql oracle pivot

我有以下查询,但查询不计入NULLs如何捕获空值?

SELECT
*
FROM (
  SELECT 
  TO_CHAR(T.END_DATE,'YYYYMM') AS MNTH_END,
  CD, CD AS CD2
  FROM T 
                               )
PIVOT
(
COUNT(CD2) 
FOR MNTH_END IN  (201801, 201802,201803,201804,201805,201806,201807,201808,201809,201810,201811,201812,201901)
)
ORDER BY CD

数据:

CD    201801 201802 201803 201804 
  A       25    26      27     28
  B      101    102    103    104
  null    0      0      0      0  

3 个答案:

答案 0 :(得分:3)

我认为您想要一些东西:

SELECT CD, 
       SUM(CASE WHEN TO_CHAR(T.END_DATE,'YYYYMM') = '201801' THEN 1 ELSE 0 END) AS "201801", 
       . . . 
       SUM(CASE WHEN TO_CHAR(T.END_DATE,'YYYYMM') = '201901' THEN 1 ELSE 0 END) AS "201901" 
FROM T 
GROUP BY CD
ORDER BY CD;

答案 1 :(得分:1)

尝试使用select id, string_agg(distinct source_field) as op from temp group by id 函数

NVL

答案 2 :(得分:1)

count()函数从不计入空值,因此问题出在COUNT(CD)上-如果CD为空,则该计数将为零,如您所见。

您可以改为计算MNTH_END的值,如果这样做,则不需要多余的CD副本:

SELECT
*
FROM (
  SELECT 
  TO_CHAR(T.END_DATE, 'YYYYMM') AS MNTH_END,
  CD
  FROM T 
)
PIVOT
(
  COUNT(MNTH_END) 
  FOR MNTH_END IN  ('201801', '201802', '201803', '201804')
)
ORDER BY CD;

在CTE中具有示例数据(包括虚空计数)的演示,并且为简洁起见,对Epivot值进行了修剪:

-- CTE for sample data
with t (cd, end_date) as (
            select 'A', date '2018-01-01' from dual connect by level <= 25
  union all select 'B', date '2018-01-01' from dual connect by level <= 101
  union all select null, date '2018-01-01' from dual connect by level <= 11
  union all select 'A', date '2018-02-01' from dual connect by level <= 26
  union all select 'B', date '2018-02-01' from dual connect by level <= 102
  union all select null, date '2018-02-01' from dual connect by level <= 12
  union all select 'A', date '2018-03-01' from dual connect by level <= 27
  union all select 'B', date '2018-03-01' from dual connect by level <= 103
  union all select null, date '2018-03-01' from dual connect by level <= 13
  union all select 'A', date '2018-04-01' from dual connect by level <= 28
  union all select 'B', date '2018-04-01' from dual connect by level <= 104
  union all select null, date '2018-04-01' from dual connect by level <= 14
)
-- actual query
SELECT
*
FROM (
  SELECT 
  TO_CHAR(T.END_DATE, 'YYYYMM') AS MNTH_END,
  CD
  FROM T 
)
PIVOT
(
  COUNT(MNTH_END) 
  FOR MNTH_END IN  ('201801', '201802', '201803', '201804')
)
ORDER BY CD;
C   '201801'   '201802'   '201803'   '201804'
- ---------- ---------- ---------- ----------
A         25         26         27         28
B        101        102        103        104
          11         12         13         14