Найти отдел, где больше, чем в среднем нет emps работают SQL - PullRequest
0 голосов
/ 04 мая 2020

Укажите название отдела, где больше, чем в среднем не работают emps

Таблица emp_demo

emp_id   dname
1        d1
2        d2
3        d3
4        d2
5        d1
6        d2

2 сотрудника в D1, 3 сотрудника в D2 и 1 сотрудник в D3.

Среднесписочная численность сотрудников будет (2 + 3 + 1/3) = 2 сотрудника Таким образом, департамент с числом сотрудников, превышающим среднее число, будет составлять D2 (с 3 сотрудниками).

Сделанный мной код запроса:

select *
from emp_demo
group by dname
having count(emp_id) > AVG(count(emp_id)) 

Ошибка

Невозможно выполнить агрегатную функцию для выражения, содержащего агрегат или подзапрос.

Ответы [ 4 ]

1 голос
/ 04 мая 2020

Ошибка вызвана SQL Сервер не позволяет агрегатной функции содержать другую агрегатную функцию.

Один из способов использовать CTE с подзапросом JOIN.

;with cte as (
    SELECT dname,COUNT(emp_id) cnt
    FROM emp_demo
    GROUP BY dname
)
SELECT t1.*
FROM cte t1 
JOIN (SELECT avg(cnt) avgCnt FROM cte) t2
ON t1.cnt > t2.avgCnt 

sqlfiddle

1 голос
/ 04 мая 2020

Используйте CTE, который возвращает среднесписочную численность работников в каждом отделе:

with cte as (
  select dname, count(*) counter
  from emp_demo
)
select dname
from cte
where counter > (select avg(counter) from cte)
1 голос
/ 04 мая 2020

Сначала вычислите среднее число emp_id, используя переменную. У этого есть подзапрос, который вычисляет число за dname, после чего основной запрос выполняет среднее значение по этому.

Вторая часть запроса - это информационная строка, сообщающая вам, какое среднее значение было получено. , Не требуется, если вы не хотите этого.

Третья часть снова запускает счет, но отфильтровывает dname записей, которые не превышают переменную @avg_emps, вычисленную в начале:

declare @avg_emps int = (
    select 
    avg(emp_count) as avg_emp_count
    from (
        select
        dname
        ,count(emp_id) as emp_count
        from dbo.foo
        group by dname
    ) as count_emps
    )

select 'Average employees per department is: ' + cast(@avg_emps as varchar(10));

select
dname
from dbo.foo
group by dname
having count(emp_id) > @avg_emps;
0 голосов
/ 04 мая 2020

Это должно работать без использования каких-либо переменных:

SELECT *
FROM emp_demo
GROUP by dname
HAVING count(emp_id) > (
    SELECT AVG(r1.c1)
    from (
        SELECT count(emp_id)) as c1
        FROM emp_demo
        GROUP by dname
    ) as r1
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...