[英]not a single-group group function using select case statement
I am writing below query which divides the two select query and calculate the percentage. 我正在写下面的查询,它划分两个选择查询并计算百分比。 But i am getting an error as not a single-group group function
但我收到错误,因为not a single-group group function
select CASE WHEN COUNT(*) = 0 THEN 0 ELSE round((r.cnt / o.cnt)*100,3) END from
(Select count(*) as cnt from O2_CDR_HEADER WHERE STATUS NOT IN(0,1) and DATE_CREATED > (SYSDATE - 1)) r cross join
(Select count(*) as cnt from O2_CDR_HEADER WHERE DATE_CREATED > (SYSDATE - 1)) o;
You are referencing an aggregate function ( COUNT(*)
) and an individual column expression ( r.cnt
and o.cnt
) in the same SELECT query. 您在同一SELECT查询中引用聚合函数( COUNT(*)
)和单个列表达式( r.cnt
和o.cnt
)。 This is not valid SQL unless a GROUP BY clause is added for the relevant individual columns. 除非为相关的各个列添加了GROUP BY子句,否则这是无效的SQL。
It would be easier to provide a valid alternative it you could clarify what you'd like this query to return (given a sample schema and set of data). 提供一个有效的替代方案会更容易,您可以澄清该查询要返回的内容(给定示例架构和数据集)。 As a guess, I'd say you can simply substitute COUNT(*)
with o.cnt
to avoid the division by 0 issue. 猜测一下,我想您可以将COUNT(*)
替换为o.cnt
以避免被0除。 If there's some other logic expected to be present here, you'd need to clarify what that is. 如果这里还有其他逻辑,则需要弄清楚这是什么。
You don't need to use joins. 您不需要使用联接。 If I were you, I'd do: 如果我是你,我会做:
select case when count(*) = 0 then 0
else round(100 * count(case when status not in (0, 1) then 1 end) / count(*), 3)
end non_0_or_1_status_percentage
from o2_cdr_header
where date_created > sysdate - 1;
Here's a simple demo: 这是一个简单的演示:
with t as (select 1 status from dual union all
select 2 status from dual union all
select 3 status from dual union all
select 2 status from dual union all
select 4 status from dual union all
select 5 status from dual union all
select 6 status from dual union all
select 7 status from dual union all
select 1 status from dual union all
select 0 status from dual union all
select 1 status from dual)
select case when count(*) = 0 then 0
else round(100 * count(case when status not in (0, 1) then 1 end) / count(*), 3)
end col1
from t
where 1=0;
COL1
----------
0
And just in case you aren't sure that doing the filtering of the count in the case statement returns the same as when you filter in the where clause, here's a demo that proves it: 并且以防万一,您不确定在case语句中对计数进行过滤是否与在where子句中进行过滤时返回的结果相同,以下是一个演示此演示的演示:
with t as (select 1 status from dual union all
select 2 status from dual union all
select 3 status from dual union all
select 2 status from dual union all
select 4 status from dual union all
select 5 status from dual union all
select 6 status from dual union all
select 7 status from dual union all
select 1 status from dual union all
select 0 status from dual union all
select 1 status from dual)
select 'using case statement' how_count_filtered,
count(case when status not in (0, 1) then 1 end) cnt
from t
union all
select 'using where clause' how_count_filtered,
count(*) cnt
from t
where status not in (0, 1);
HOW_COUNT_FILTERED CNT
-------------------- ----------
using case statement 7
using where clause 7
It looks like you want to get a percentage of status not in 0,1, or 0 if there is no results. 看起来您希望获得的状态百分比不在0,1或0中(如果没有结果)。
Maybe this is what you want for the first line? 也许这就是您想要的第一行?
SELECT CASE WHEN (R.CNT = 0 AND O.CNT = 0) THEN 0 ELSE ROUND((R.CNT *100.0 / O.CNT),3) END
You don't need a cross join. 您不需要交叉连接。 Select the counts and do a division later on. 选择计数,然后进行除法。
select case when ocnt > 0 then round((rcnt / ocnt)*100,3)
else 0 end
from
(
select
CASE WHEN STATUS NOT IN(0,1) and DATE_CREATED > (SYSDATE - 1)
THEN COUNT(*) END as rcnt,
CASE WHEN DATE_CREATED > (SYSDATE - 1)
THEN COUNT(*) END as ocnt
from O2_CDR_HEADER
group by status, date_created
) t
Boneist's answer is fine, but I would write it as: Boneist的回答很好,但我将其写为:
select coalesce(round(100 * avg(case when status not in (0, 1) then 1.0 else 0
end), 3), 0) as non_0_or_1_status_percentage
from o2_cdr_header
where date_created > sysdate - 1;
Here is the answer which works perfectly for me 这是最适合我的答案
select CASE WHEN (o.cnt = 0) THEN 0 ELSE round((r.cnt / o.cnt)*100,3) END from
(Select count(*) as cnt from O2_CDR_HEADER WHERE STATUS NOT IN(0,1) and DATE_CREATED > (SYSDATE - 1)) r cross join
(Select count(*) as cnt from O2_CDR_HEADER WHERE DATE_CREATED > (SYSDATE - 1)) o
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.