#sql-server #database #aggregate
Вопрос:
Я использую SQL Server и пытаюсь получить минимальные средние зарплаты по нескольким отделам или группам по их отделам.
Я могу получить средние значения заработной платы по всем отделам (по группам) с помощью этого запроса:
select d.Dname, avg(e.salary) as averagr_salary
from Employee e, Departments d
where d.Dnum = e.dno
group by e.Dno,d.Dname
Результаты таких данных (имя отдела и среднее значение):
name avg
----------
DP1 139
DP2 1050
DP3 1250
Я хочу получить только минимум из этих нескольких средних, подобных этому:
name avg
---------
DP1 139
Я попытался выполнить этот запрос, но получаю ошибки:
select
d.Dname, min(avg(e.salary)) as averagr_salary
from
Employee e, Departments d
where
d.Dnum = e.dno
group by
e.Dno, d.Dname
Ошибка:
Невозможно выполнить агрегатную функцию для выражения, содержащего агрегат или подзапрос.
Не могли бы вы мне помочь?
Комментарии:
1. Оберните
avg
агрегацию во внешнийmin
запрос.2. Не могли бы вы объяснить, как
3. Совет сегодняшнего дня: Переключитесь на современный, явный
JOIN
синтаксис. Легче писать (без ошибок), легче читать (и поддерживать), и легче конвертировать во внешнее соединение, если это необходимо
Ответ №1:
Скрипка (обновлено): https://dbfiddle.uk/?rdbms=sqlserver_2019amp;fiddle=bb4d5b2989e06f92bcb8c39742798ba4
Некоторые элементы управления пользовательским интерфейсом stackoverflow ведут себя странно. Многие обычные элементы управления, такие как комментарии, элементы управления редактированием и т.д., Не функционируют уже около 12 часов.
Это решение является стандартным SQL и будет работать с SQL Server (последние версии); также обратите внимание, что логика работает, когда есть несколько групп со средним значением, которое соответствует минимуму, а не только одна.
WITH cte AS
(
SELECT
d.Dname,
AVG(e.salary) AS average_salary,
RANK() OVER (ORDER BY AVG(e.salary)) AS n
FROM
Employee e
JOIN
Departments d ON d.Dnum = e.Dno
GROUP BY
e.Dno, d.Dname
)
SELECT Dname, average_salary
FROM cte
WHERE n = 1;
Комментарии:
1. Большое спасибо за ваш ответ, но я использую SQL server НЕ (MYSQL), поэтому при использовании (ОГРАНИЧЕНИЕ) возникает синтаксическая ошибка, извините за этот конфликт, поэтому я удалил тег (MYSQL) и отредактировал свой вопрос
2. Большое спасибо, это работает
Ответ №2:
Это должно быть что-то вроде:
Select tbl.Dname,min(averagr_salary) as averagr_salary
from
(
select d.Dname,avg(e.salary) as averagr_salary
from Employee e
inner join Departments d
on d.Dnum = e.dno
group by e.Dno,d.Dname
) as tbl
group by tbl.Dname
order by averagr_salary ASC limit 1;
Демо: https://www.db-fiddle.com/f/vhqJXYFy52xRtVBc97R1EL/1
Для SQL Server:
Select top 1 tbl.Dname,min(averagr_salary) as averagr_salary
from
(
select d.Dname,avg(e.salary) as averagr_salary
from Employee e
inner join Departments d
on d.Dnum = e.dno
group by e.Dno,d.Dname
) as tbl
group by tbl.Dname
order by averagr_salary ASC;
Демо:https://dbfiddle.uk/?СУБД=sqlserver_2019 и скрипка=303b9fab3403397b1df8ee79b9b216a6
Комментарии:
1. Тот же результат, он показывает все средние значения, а не только минимальное среднее значение
2. Большое спасибо за ваш ответ, но я использую SQL server НЕ (MYSQL), поэтому при использовании (ОГРАНИЧЕНИЕ) возникает синтаксическая ошибка, извините за этот конфликт, поэтому я удалил тег (MYSQL) и отредактировал свой вопрос
3. Большое спасибо, это работает