Рассчитать процентные строки по некоторому конкретному значению

Есть ли какая-либо функция оракула, которая поможет мне рассчитать процент строк, который принимает некоторые условия

Пример таблицы:

   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;

DBFiddle Demo

Выход:

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

dbfiddle

Другие вопросы по тегам