2014-09-23 1 views
1

Учитывая эти данные, как я могу написать 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 */ 

ответ

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 Скрипки.

EDIT:

Это то, что вы хотите?

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; 
+0

Гордон, я бы хотел получить итоговые значения только для ранжированных рядов. т. е. сводка и счетчик только для id = 123 (400 баллов) + 345 (600 баллов); id = 222 имеет 200, потому что их ранжирование по seqno 1. Когда я использую раздел для ранжирования моих строк, мое предложение group by в конце вызывает ошибки. – zundarz

+0

Да, это теоретически то, что я хочу, но 'group by dept_id' и' partition by ', похоже, не работают хорошо для меня. Во втором запросе я получаю сообщение об ошибке «ORA-00979: не сообщение GROUP BY». – zundarz

+0

@zundarz. , , Нет, нет. «Группа за» оказалась не в том месте. –