如果我查询不存在的输出,那么我将不会返回任何内容。我正在寻找在该场景中返回的默认值(0)
select sum(case when a2.status='SUCCESS' THEN A2.a else 0 end) as success,
sum(case when a2.status='FAILED' THEN A2.a else 0 end) as failed,
sum(case when a2.status='ERROR' THEN A2.a else 0 end) as error
from
(select a.stauts,count(1) a
from table1 a,table2 b
where a.id=b.id
a.date=sysdate
group by a.status)a2;
注意:sysdate没有记录。我要求默认值“0”应该返回状态。
答案 0 :(得分:2)
此查询应始终返回一行,即使没有匹配项:
select sum(case when a.status = 'SUCCESS' then 1 else 0 end) as success,
sum(case when a.status = 'FAILED' then 1 else 0 end) as failed,
sum(case when a.status = 'ERROR' then 1 else 0 end) as error
from table1 a join
table2 b
on a.id = b.id
where a.date = trunc(sysdate);
请注意,我更改了where
逻辑。 sysdate
(尽管它的名字)有一个时间组件。如果date
有时间组件,您可能需要:
where a.date >= trunc(sysdate) and a.date < trunc(sysdate + 1)
编辑:
如果过滤条件没有匹配任何行,那么您将使用:
获得0
select count(case when a.status = 'SUCCESS' then 1 end) as success,
count(case when a.status = 'FAILED' then 1 end) as failed,
count(case when a.status = 'ERROR' then 1 end) as error
from table1 a join
table2 b
on a.id = b.id
where a.date = trunc(sysdate);
答案 1 :(得分:0)
您可以生成缺失值:
WITH cte AS (
select a.status,count(1) a
from table1 a --JOIN syntax
join table2 b
on a.id=b.id
WHERE a.date=sysdate -- are you sure you want precision with time?
group by a.status
), placeholder AS (
SELECT *
FROM cte
UNION ALL
SELECT *
FROM (SELECT 'SUCCESS' AS status, 0 AS a FROM dual UNION ALL
SELECT 'ERROR', 0 FROM dual UNION ALL
SELECT 'FAILED', 0 FROM dual) p
WHERE NOT EXISTS (SELECT * FROM cte WHERE cte.status = p.status)
)
SELECT
sum(case when status='SUCCESS' THEN a else 0 end) as success,
sum(case when status='FAILED' THEN a else 0 end) as failed,
sum(case when status='ERROR' THEN a else 0 end) as error
FROM placeholder;
答案 2 :(得分:0)
我想到的唯一建议是在子查询中使用左连接并将整个WHERE
逻辑移动到ON
子句:
SELECT
SUM(CASE WHEN a2.status = 'SUCCESS' THEN A2.a ELSE 0 END) AS success,
SUM(CASE WHEN a2.status = 'FAILED' THEN A2.a ELSE 0 END) AS failed,
SUM(CASE WHEN a2.status = 'ERROR' THEN A2.a ELSE 0 END) AS error
FROM
(
SELECT a.status, COUNT(1) a
FROM table1 a
LEFT JOIN table2 b
ON a.id = b.id AND
a.date = SYSDATE
GROUP BY a.status
) a2;
您当前的查询使用的是古老的连接语法,这使得很难看到实际发生的情况。特别是,在您希望保留的加入期间,您很难看到是否可能丢弃信息。
答案 3 :(得分:0)
如果您使用COUNT()
,则与NVL()
的情况不同,您不需要COALESCE()
或NULL
来处理SUM()
。当参数为COUNT()
或没有匹配行时,NULL
将始终返回 value = 0 的行。GROUP BY
也不需要。{ / p>
SELECT COUNT(CASE WHEN a.status = 'SUCCESS' THEN 1 END) AS success,
COUNT(CASE WHEN a.status = 'FAILED' THEN 1 END) AS failed,
COUNT(CASE WHEN a.status = 'ERROR' THEN 1 END) AS error
FROM table1 a
JOIN table2 b ON a.id = b.id
WHERE a.date = TRUNC(SYSDATE);
如果您只是想清楚,请测试这些查询并注意结果。
select SUM(1) FROM DUAL WHERE 1=0; --NULL
select SUM(NULL) FROM DUAL WHERE 1=0; --NULL
select SUM(NULL) FROM DUAL WHERE 1=1; --NULL
select COUNT(1) FROM DUAL WHERE 1=0; -- 0
select COUNT(NULL) FROM DUAL WHERE 1=0; -- 0
select COUNT(NULL) FROM DUAL WHERE 1=1; -- 0
答案 4 :(得分:0)
Aggregation without GROUP BY always returns a row, so your existing query will return NULLs.
To change a NULL to zero simply apply COALESCE:
select
coalesce(sum(case when a2.status='SUCCESS' THEN A2.a end), 0) as success,
coalesce(sum(case when a2.status='FAILED' THEN A2.a end), 0) as failed,
coalesce(sum(case when a2.status='ERROR' THEN A2.a end), 0) as error
from
(
select a.status,count(1) a
from table1 a join table2 b
on a.id=b.id
where a.date=sysdate
group by a.status
) a2;
答案 5 :(得分:0)
如果我想确保即使对于找不到任何要返回的行的查询也总会有结果,我会在双表上进行左连接(对于oracle):
select q.* FROM DUAL d LEFT JOIN ( your_query )q on 1=1
通过这种方式,无论如何,你总会得到一排!