合并、nvl 和 CASE 不适用于子查询中的计数 (*)
coalesce, nvl and CASE not working for count(*) in the subquery
我有一个 CTE 查询,我希望 NULL 行为 0。
我想知道为什么 COALESCE(tsting)、NVL(tsting2) 和 CASE(rw_cnt) 不起作用?我错过了什么吗?
with dte AS(Select store, date_id from store cross JOIN (SELECT
(TRUNC(sysdate)-1 + (LEVEL-10)) AS DATE_ID
FROM DUAL connect by level <=( (sysdate-2)-(sysdate-10)))
store<10)
, tmp as(Select calendar_dt, str, CASE WHEN rw_cnt IS NULL THEN 0 ELSE rw_cnt
END rw_cnt, COALESCE(rw_cnt, 0) tsting, NVL(rw_cnt, 0 ) tsting2
from (SELECT calendar_dt, str, count(*) rw_cnt FROM table2 group by calendar_dt, str))
Select store, date_id, rw_cnt, case when rw_cnt IS NULL THEN 0 ELSE rw_cnt END testing,
tsting, tsting2 from dte LEFT OUTER JOIN tmp ON dte.date_id = tmp.calendar_dt
AND dte.store = temp.store
order by store, date_id;
我得到如下数据:
+-------+-----------+--------+---------+--------+---------+
| STORE | DATE_ID | RW_CNT | TESTING | TSTING | TSTING2 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 18-OCT-20 | NULL | 0 | NULL | NULL |
+-------+-----------+--------+---------+--------+---------+
| 3 | 19-OCT-20 | 73 | 73 | 73 | 73 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 20-OCT-20 | 88 | 88 | 88 | 88 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 21-OCT-20 | 63 | 63 | 63 | 63 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 22-OCT-20 | 100 | 100 | 100 | 100 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 23-OCT-20 | 105 | 105 | 105 | 105 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 24-OCT-20 | 36 | 36 | 36 | 36 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 25-OCT-20 | 3 | 3 | 3 | 3 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 18-OCT-20 | NULL | 0 | NULL | NULL |
+-------+-----------+--------+---------+--------+---------+
| 4 | 19-OCT-20 | 30 | 30 | 30 | 30 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 20-OCT-20 | 24 | 24 | 24 | 24 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 21-OCT-20 | 38 | 38 | 38 | 38 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 22-OCT-20 | 21 | 21 | 21 | 21 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 23-OCT-20 | 37 | 37 | 37 | 37 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 24-OCT-20 | 3 | 3 | 3 | 3 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 25-OCT-20 | NULL | 0 | NULL | NULL |
+-------+-----------+--------+---------+--------+---------+
欢迎就查询优化提出任何建议...:)
您正在执行 dte
到 tmp
的 LEFT
连接,因此对于不匹配的行您会得到 null
s。
也许你认为在tmp
中使用COALESCE()
和NVL()
最终结果将显示0
而不是null
,但这是不对的。
COALESCE()
和 NVL()
是 tmp
内部的,如果你从 tmp
select 只有这样你就不会得到 null
s,但既然你这样做了LEFT
join 并且存在不匹配的行,那么这些不匹配的行的列将由 null
s.
表示
因此,如果要删除这些 null
,则必须在最后的 SELECT
语句中使用 COALESCE()
and/or NVL()
。
我有一个 CTE 查询,我希望 NULL 行为 0。
我想知道为什么 COALESCE(tsting)、NVL(tsting2) 和 CASE(rw_cnt) 不起作用?我错过了什么吗?
with dte AS(Select store, date_id from store cross JOIN (SELECT
(TRUNC(sysdate)-1 + (LEVEL-10)) AS DATE_ID
FROM DUAL connect by level <=( (sysdate-2)-(sysdate-10)))
store<10)
, tmp as(Select calendar_dt, str, CASE WHEN rw_cnt IS NULL THEN 0 ELSE rw_cnt
END rw_cnt, COALESCE(rw_cnt, 0) tsting, NVL(rw_cnt, 0 ) tsting2
from (SELECT calendar_dt, str, count(*) rw_cnt FROM table2 group by calendar_dt, str))
Select store, date_id, rw_cnt, case when rw_cnt IS NULL THEN 0 ELSE rw_cnt END testing,
tsting, tsting2 from dte LEFT OUTER JOIN tmp ON dte.date_id = tmp.calendar_dt
AND dte.store = temp.store
order by store, date_id;
我得到如下数据:
+-------+-----------+--------+---------+--------+---------+
| STORE | DATE_ID | RW_CNT | TESTING | TSTING | TSTING2 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 18-OCT-20 | NULL | 0 | NULL | NULL |
+-------+-----------+--------+---------+--------+---------+
| 3 | 19-OCT-20 | 73 | 73 | 73 | 73 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 20-OCT-20 | 88 | 88 | 88 | 88 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 21-OCT-20 | 63 | 63 | 63 | 63 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 22-OCT-20 | 100 | 100 | 100 | 100 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 23-OCT-20 | 105 | 105 | 105 | 105 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 24-OCT-20 | 36 | 36 | 36 | 36 |
+-------+-----------+--------+---------+--------+---------+
| 3 | 25-OCT-20 | 3 | 3 | 3 | 3 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 18-OCT-20 | NULL | 0 | NULL | NULL |
+-------+-----------+--------+---------+--------+---------+
| 4 | 19-OCT-20 | 30 | 30 | 30 | 30 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 20-OCT-20 | 24 | 24 | 24 | 24 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 21-OCT-20 | 38 | 38 | 38 | 38 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 22-OCT-20 | 21 | 21 | 21 | 21 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 23-OCT-20 | 37 | 37 | 37 | 37 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 24-OCT-20 | 3 | 3 | 3 | 3 |
+-------+-----------+--------+---------+--------+---------+
| 4 | 25-OCT-20 | NULL | 0 | NULL | NULL |
+-------+-----------+--------+---------+--------+---------+
欢迎就查询优化提出任何建议...:)
您正在执行 dte
到 tmp
的 LEFT
连接,因此对于不匹配的行您会得到 null
s。
也许你认为在tmp
中使用COALESCE()
和NVL()
最终结果将显示0
而不是null
,但这是不对的。
COALESCE()
和 NVL()
是 tmp
内部的,如果你从 tmp
select 只有这样你就不会得到 null
s,但既然你这样做了LEFT
join 并且存在不匹配的行,那么这些不匹配的行的列将由 null
s.
因此,如果要删除这些 null
,则必须在最后的 SELECT
语句中使用 COALESCE()
and/or NVL()
。