Рассчитать процентные строки по некоторому конкретному значению
Есть ли какая-либо функция оракула, которая поможет мне рассчитать процент строк, который принимает некоторые условия
Пример таблицы:
WorkerId Salary DepartmentId
10001 2000.00 1
10002 2500.00 2
10004 3000.00 1
10005 3500.00 1
Хотелось бы узнать, каков процент работников с зарплатой более 2100,00 на каждый отдел
3 ответа
Вы могли бы использовать RATIO_TO_REPORT
:
SELECT departmentID, 100 * SUM(rr) AS total_percentage
FROM (SELECT t.*, RATIO_TO_REPORT(1) OVER (PARTITION BY DepartmentId) AS rr
FROM your_tab t) s
WHERE salary > 2100
GROUP BY departmentId;
Выход:
DEPARTMENTID TOTAL_PERCENTAGE
1 66.66
2 100
Вы можете сделать это без использования аналитической функции, например так:
WITH sample_data AS (SELECT 10001 workerid, 2000 salary, 1 departmentid FROM dual UNION ALL
SELECT 10002 workerid, 2500 salary, 2 departmentid FROM dual UNION ALL
SELECT 10004 workerid, 3000 salary, 1 departmentid FROM dual UNION ALL
SELECT 10005 workerid, 3500 salary, 1 departmentid FROM dual)
-- end of subquery mimicking a table with your data in it.
-- see SQL query below:
SELECT departmentid,
100*(COUNT(CASE WHEN salary > 2100 THEN 1 END)/COUNT(*)) pct_earning_gt_2100
FROM sample_data
GROUP BY departmentid;
DEPARTMENTID PCT_EARNING_GT_2100
------------ -------------------
1 66.6666666666667
2 100
При этом используется условный счетчик (помните, что нулевые значения игнорируются большинством агрегатных функций), чтобы определить, сколько строк соответствует условию, перед делением на общее количество строк на отдел.
Это должно быть более производительным, чем решение, включающее аналитическую функцию ratio_to_report, так как ему не нужно делать этот дополнительный шаг, прежде чем выполнять группировку, но вы должны протестировать оба решения, чтобы выяснить, какое из них действительно лучше с вашими данными.
Попробуйте использовать два GROUP BY
а также JOIN
SELECT yt.DepartmentId, t.hs/count(*) * 100
FROM your_tab yt
JOIN
(
SELECT DepartmentId, count(*) as hs
FROM your_tab
WHERE salary > 2100
GROUP BY DepartmentId
) t ON yt.DepartmentId = t.DepartmentId
GROUP BY yt.DepartmentId, t.hs