鉴于这些数据,如何编写SQL以便为每个显示摘要的部门返回一行,并仅计算排名行的数量?
with data_row as
( select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender, 'A' as seqno, 400 as score from dual union all
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender,'B' as seqno, 500 as score from dual union all
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender,'C' as seqno, 300 as score from dual union all
select '345' as emp_id, 'AAA' as dept_id, 'F' as emp_gender,'A' as seqno, 600 as score from dual union all
select '345' as emp_id, 'AAA' as dept_id, 'F' as emp_gender,'B' as seqno, 700 as score from dual union all
select '222' as emp_id, 'BBB' as dept_id, 'F' as emp_gender,'A' as seqno, 200 as score from dual union all
select '222' as emp_id, 'BBB' as dept_id, 'F' as emp_gender,'B' as seqno, 800 as score from dual
)
select dept_id,
sum(score) over ( partition by dept_id) as rnk_1_sum,
count(*) over (partition by dept_id) as dept_count,
count(*) over (partition by emp_gender) as male_count,
count(*) over (partition by emp_gender) as female_count
from ( select emp_id,
dept_id,
seqno,
score,
emp_gender,
rank() over (partition by emp_id
order by seqno) as rnk
from data_row
)
where rnk=1
-- group by dept_id -- Including this line yields a ORA-00979: not a GROUP BY expression
期望的结果
DEPT_ID RNK_1_SUM DEPT_COUNT MALE_COUNT FEMALE_COUNT
------- ---------- ---------- ---------- ------------
AAA 1000 2 1 1 /* 123.score + 345.score = 400 + 600 */
BBB 200 1 0 1 /* 222.score = 200 */
答案 0 :(得分:2)
只需使用聚合:
with data_row as (
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender, 'A' as seqno, 400 as score from dual union all
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender,'B' as seqno, 500 as score from dual union all
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender,'C' as seqno, 300 as score from dual union all
select '345' as emp_id, 'AAA' as dept_id, 'F' as emp_gender,'A' as seqno, 600 as score from dual union all
select '345' as emp_id, 'AAA' as dept_id, 'F' as emp_gender,'B' as seqno, 700 as score from dual union all
select '222' as emp_id, 'BBB' as dept_id, 'F' as emp_gender,'A' as seqno, 200 as score from dual union all
select '222' as emp_id, 'BBB' as dept_id, 'F' as emp_gender,'B' as seqno, 800 as score from dual
)
select dept_id,
sum(score) as rnk_1_sum,
count(*) as dept_count,
sum(case when emp_gender = 'M' then 1 else 0 end) as male_count,
sum(case when emp_gender = 'F' then 1 else 0 end) as female_count
from data_row
group by dept_id;
Here是一个SQL小提琴。
编辑:
这是你想要的吗?
with data_row as (
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender, 'A' as seqno, 400 as score from dual union all
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender,'B' as seqno, 500 as score from dual union all
select '123' as emp_id, 'AAA' as dept_id, 'M' as emp_gender,'C' as seqno, 300 as score from dual union all
select '345' as emp_id, 'AAA' as dept_id, 'F' as emp_gender,'A' as seqno, 600 as score from dual union all
select '345' as emp_id, 'AAA' as dept_id, 'F' as emp_gender,'B' as seqno, 700 as score from dual union all
select '222' as emp_id, 'BBB' as dept_id, 'F' as emp_gender,'A' as seqno, 200 as score from dual union all
select '222' as emp_id, 'BBB' as dept_id, 'F' as emp_gender,'B' as seqno, 800 as score from dual
)
select dept_id,
sum(score) as rnk_1_sum,
count(*) as dept_count,
sum(case when emp_gender = 'M' then 1 else 0 end) as male_count,
sum(case when emp_gender = 'F' then 1 else 0 end) as female_count
from (select e.*, row_number() over (partition by emp_id order by seqno) as seqnum
from data_row
) d
where seqnum = 1
group by dept_id;