[英]Use Count function inside conditional part of Case Expression
I have two tables with the following sample records in oracle database 我在Oracle数据库中有两个带有以下示例记录的表
1. staffs 1.员工
inst_name name sid
ABC John 1
PQR Sam 2
ABC Tom 3
ABC Amit 4
PQR Jack 5
2. staffaccounts 2.人员账户
sid account_no
1 4587
1 4588
2 4589
3 4581
3 4582
5 4583
5 4585
4 4586
Where I want the result like 我想要的结果像
inst_name account_type total
PQR SINGLE 1
ABC SINGLE 1
PQR DOUBLE 1
ABC DOUBLE 2
This can be achieved by a outer query, but I want to write a query where there is no outer query. 这可以通过外部查询来实现,但是我想编写一个没有外部查询的查询。 Want to accomplish it in one single query.
想要在一个查询中完成。
SELECT
A .inst_name,
(
CASE COUNT (b.ac_no)
WHEN 1 THEN
'Single'
WHEN 2 THEN
'Double'
END
) account_type,
COUNT (A . NAME)
FROM
staffs A,
staffaccounts b
WHERE
A . s_id = b.s_id
GROUP BY
A .inst_name
The above query gives error ORA-00907: missing right parenthesis
. 上面的查询给出错误
ORA-00907: missing right parenthesis
。 Can it be done in single query or is outer query the only way out. 可以在单个查询中完成还是外部查询是唯一的出路。
Oracle Version is 10g
May be something like this would work. 可能像这样会起作用。
SELECT
A.inst_name,
CASE COUNT (b.account_no)
WHEN 1 THEN
'Single'
WHEN 2 THEN
'Double'
END account_type,
COUNT (A.name)
FROM
staffs A JOIN
staffaccounts b
ON
A.SID = b.sid
GROUP BY
A.inst_name , a.sid
ORDER BY 3;
You should learn how to properly use JOIN
syntax. 您应该学习如何正确使用
JOIN
语法。 I prefer the explicit comparison syntax for CASE
. 我更喜欢
CASE
的显式比较语法。
This may be what you want: 这可能是您想要的:
SELECT s.inst_name,
(CASE WHEN COUNT(sa.ac_no) = 1 THEN 'Single'
WHEN COUNT(sa.ac_no) = 2 THEN 'Double'
END) as account_type,
COUNT(*)
FROM staffs s JOIN
staffaccounts sa
ON s.SID = sa.sid
GROUP BY s.inst_name;
EDIT: 编辑:
Now I see what you want: 现在我明白了你想要什么:
SELECT s.inst_name,
(CASE WHEN cnt = 1 THEN 'Single'
WHEN cnt = 2 THEN 'Double'
END) as account_type,
COUNT(*)
FROM (SELECT s.*, COUNT(*) as cnt
FROM staffs s JOIN
staffaccounts sa
ON s.SID = sa.sid
GROUP BY s.id
) s
GROUP BY s.inst_name,
(CASE WHEN cnt = 1 THEN 'Single'
WHEN cnt = 2 THEN 'Double'
END);
You are grouping by inst_name
, but this is not what you actually want, because you don't want a result row per inst_name
, but per inst_name
and account_type
. 您正在按
inst_name
分组,但这并不是您真正想要的,因为您不希望每个inst_name
而是每个inst_name
和account_type
都存在结果行。
select
s.inst_name,
sa.account_type,
count(*) as total
from staffs s
join
(
select
sid,
case when count(*) = 1 then 'SINGLE' else 'DOUBLE' end as account_type
from staffaccounts
group by sid
having count(*) <= 2
) sa on sa.sid = s.sid
group by sa.account_type, s.inst_name
order by sa.account_type, s.inst_name;
I got only the way by using subquery
but is in the easy way (more easier and readable)
to achieve your requirement 我只能通过使用
subquery
但是以一种简单的方式(more easier and readable)
可以满足您的要求
SELECT inst_name, account_type, count(total) as total
FROM (
SELECT
a.inst_name,
CASE
WHEN COUNT (b.account_no) = 1 THEN 'Single'
WHEN COUNT (b.account_no) = 2 THEN 'Double'
END AS account_type,
COUNT (a.name) AS total
FROM staffs a
INNER JOIN staffaccounts b ON A . SID = b.sid
GROUP BY a.inst_name, a.sid) t GROUP BY inst_name, account_type
OUTPUT : 输出 :
inst_name account_type total
ABC Double 2
PQR Double 1
ABC Single 1
PQR Single 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.