2016-11-14 5 views
0

У меня есть задача рассчитать наименьшую зарплату в отделах и сколько процентов это от общей зарплаты. Также я могу использовать только один оператор select и возможно Мне нужно использовать функции окна.Как рассчитать процент в столбце?

Это, как я начал:

 SELECT distinct department_id, 
    min(salary) over(partition by department_id) as min_sal 
    FROM employees; 

Но если я использую функцию RATIO_TO_REPORT это показать всю таблицу, не сгруппированные по DEPARTMENT_ID.

+0

Нужна ли вам одна строка на одного сотрудника на выходе (очень странно) или всего одна строка за ДЕПАРТАМЕНТ? Или вам нужно получить имя сотрудника с самой низкой зарплатой? – mathguy

+0

Поделитесь некоторым набором данных выборки и ожидаемым результатом. – XING

ответ

1

Похоже

select min(salary) as min_salary, round(min(salary)/sum(salary) * 100 , 1) as percent 
from employees 
group by department_id 
; 

Если вам также нужно имя сотрудника, который имеет наименьшую зарплату в каждом отделе (предполагается, что всегда есть только один), а затем добавить

, min(empl_name) keep (dense_rank first order by salary) as min_sal_empl_name 

в SELECT заявлении. Если могут быть связи за наименьшую зарплату, и вам нужны все сотрудники, скажите об этом - в этом случае вам, вероятно, нужны аналитические функции, как вы догадались. Что-то вроде:

select empl_name, salary, round(salary/tot_sal*100, 1) as percent 
from (select empl_name, salary, 
       sum(salary) over (partition by department_id)   as tot_sal, 
       rank() over (partition by department_id order by salary) as rn 
     from employees 
     ) 
where rn = 1 
; 

Добавлено: OP указали, что они нуждаются зарплату в процентах от общей заработной платы (по всем подразделениям) после всех. Это можно сделать, объединив ratio_to_report() с пустым условием окон (без «раздела на») с rank(), разделенным отделом, чтобы получить наименьшую зарплату в каждом отделе.

Если вам не нравится over() для пункта взвешивания в ratio_to_report(), он также может быть записан в виде over (partition by null), чтобы сделать его супер-ясно нет разделения не предназначен или необходимости.

Решение использует таблицу EMP в схеме SCOTT для тестирования, поскольку исходное сообщение не содержит данные образца.

select deptno, empno, ename, sal, percent 
from (
     select empno, ename, sal, deptno, 
       round(100 * ratio_to_report(sal) over(), 1) as percent, 
       rank() over (partition by deptno order by sal) as rn 
     from scott.emp 
     ) 
where rn = 1 
; 


DEPTNO EMPNO ENAME SAL PERCENT 
------ ----- ------ ---- ------- 
10  7934 MILLER 1300  4.5 
20  7369 SMITH 800  2.8 
30  7900 JAMES 950  3.3 
+0

да, мне нужно все они, и я использовал запрос, похожий на ваш последний, но есть уловка, он может выбрать оператор select. И ваш первый запрос идеален во всех отношениях, за исключением того, что он вычисляет, как проценты неправильным образом. –

+0

@ E.Saraf - Оператор select с подзапросом (оператор подвыбора) по-прежнему представляет собой один оператор select. Затем: если вы считаете, что мой первый расчет ошибочен, объясните, как это неправильно, иначе я не могу вас серьезно отнести. (Возможно, вы все равно ошибаетесь, но я не могу сказать вам, как если вы не разделяете то, что считаете неверным.) – mathguy

+0

Ваши расчеты правильные. Но мне нужно знать, сколько процентов минимальной зарплаты отдела составляет от общей суммы, а не от суммы департамента. Во втором запросе легко исправить, но есть ли способ сделать это в первом запросе? –

Смежные вопросы