Получение названий отделов с максимальным количеством сотрудников - PullRequest
0 голосов
/ 10 июня 2019

У меня есть 2 таблицы, одна таблица, в которой хранятся сведения о персонале (столбцы: staff_id, staff_name, департамент_id), а другая таблица, в которой хранятся данные отдела (столбцы департамент_id, отдел_имя, отдел_блок_num).

Мне нужно написать запрос для отображения названий отделов, в которых указана максимальная численность персонала по названию отдела.Также считается, что в нескольких отделах количество сотрудников может быть таким же, как и максимальное количество сотрудников.Другое условие групповой функции не допускается.

Вот код

SELECT department_name
  FROM department
 WHERE department_id IN (SELECT department_id
                           FROM (  SELECT department_id, COUNT (*) AS cnt1
                                     FROM staff
                                    WHERE COUNT (*) =
                                             (SELECT cnt
                                                FROM (  SELECT department_id,
                                                               COUNT (*) AS cnt
                                                          FROM staff
                                                      GROUP BY department_id
                                                      ORDER BY cnt DESC)
                                               WHERE ROWNUM = 1)
                                 GROUP BY department_id));

Ответы [ 3 ]

0 голосов
/ 10 июня 2019

Вы можете использовать аналитическую функцию RANK, чтобы найти строки с максимальным количеством:

SELECT   department_id,
         COUNT(*) AS cnt,
         RANK() OVER ( ORDER BY COUNT(*) DESC ) AS rnk
FROM     staff
GROUP BY department_id

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

Oracle Setup :

CREATE SEQUENCE staff__id__seq;

CREATE TABLE departments (
  id              INT PRIMARY KEY,
  department_name VARCHAR2(20)
);

INSERT INTO departments ( id, department_name )
  SELECT 1, 'Aaa' FROM DUAL UNION ALL
  SELECT 2, 'Bbb' FROM DUAL UNION ALL
  SELECT 3, 'Ccc' FROM DUAL UNION ALL
  SELECT 4, 'Ddd' FROM DUAL;

CREATE TABLE staff (
  id INT PRIMARY KEY,
  department_id INT REFERENCES departments( id )
);

INSERT INTO staff ( id, department_id )
SELECT staff__id__seq.NEXTVAL, department_id
FROM (
  SELECT 1 AS department_id FROM DUAL CONNECT BY LEVEL <= 3 UNION ALL
  SELECT 2                  FROM DUAL CONNECT BY LEVEL <= 5 UNION ALL
  SELECT 3                  FROM DUAL CONNECT BY LEVEL <= 2 UNION ALL
  SELECT 4                  FROM DUAL CONNECT BY LEVEL <= 5
);

Запрос на подсчет персонала :

SELECT   department_id,
         COUNT(*) AS cnt,
         RANK() OVER ( ORDER BY COUNT(*) DESC ) AS rnk
FROM     staff
GROUP BY department_id
DEPARTMENT_ID | CNT | RNK
------------: | --: | --:
            2 |   5 |   1
            4 |   5 |   1
            1 |   3 |   3
            3 |   2 |   4

Запрос 2 - Получить название отдела для наивысших показателей :

Просто присоедините предыдущий запрос к таблице departments ифильтр для возврата строк, когда ранг равен 1 (наибольшее число).

SELECT d.department_name
FROM   (
         SELECT   department_id,
                  RANK() OVER ( ORDER BY COUNT(*) DESC ) AS rnk
         FROM     staff
         GROUP BY department_id
       ) s
       INNER JOIN departments d
       ON ( d.id = s.department_id )
WHERE  s.rnk = 1

Выход :

| DEPARTMENT_NAME |
| :-------------- |
| Bbb             |
| Ddd             |

db <> fiddle здесь

0 голосов
/ 10 июня 2019

Предполагая, что это домашнее задание или что-то подобное, и что функция windows не разрешена, здесь есть решение, использующее более простой sql

SELECT department_name
FROM department d
JOIN staff s ON d.department_id = s.department_id
GROUP BY department_name
HAVING COUNT(s.department_id) = (SELECT COUNT(*) as stat 
    FROM staff 
    GROUP BY department_id 
    ORDER BY stat DESC
    FETCH FIRST ROW ONLY)
ORDER BY department_name
0 голосов
/ 10 июня 2019

Если вы пытаетесь избежать group by, используйте подзапросы:

select d.*,
       (select count(*)
        from staff s
        where s.department_id = d.department_id
       ) as staff_cnt
from department d;

Если вы хотите, чтобы верхние отделы со связями использовали подзапросы и оконные функции:

select . . .   -- whatever columns you want
from (select d.*,
           rank() over (order by staff_cnt desc) as seqnum
      from (select d.*,
                   (select count(*)
                    from staff s
                    where s.department_id = d.department_id
                   ) as staff_cnt
            from department d
           ) d
      ) d
where seqnum = 1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...