如何从排名行中获取汇总值?

时间:2014-09-23 01:44:28

标签: sql oracle rank window-functions summary

鉴于这些数据,如何编写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 */

1 个答案:

答案 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;