Ms sql select в select: Вложенные запросы (SQL Server) — SQL Server
Содержание
Не получается сделать SELECT FROM SELECT [MS SQL Server]
Вопрос задан
Изменён
5 лет 4 месяца назад
Просмотрен
26k раза
Есть таблица Сотрудники (Employees) и Отделы (Departments).
Необходимо найти такие отделы, в которых суммарная зарплата сотрудников будет наибольшей.
Вот наполнение самих таблиц
Дошел только до того, что нашел максимальную сумму
SELECT MAX(A.SUM_Money) FROM ( SELECT Dep_number, SUM(Cash_bonus + Salary) AS SUM_Money FROM Employees GROUP BY Dep_number ) AS A
Только вот никак не могу вывести рядом поле с номером отдела
SELECT A.Dep_number, MAX(A.SUM_Money) FROM ( SELECT Dep_number, SUM(Cash_bonus + Salary) AS SUM_Money FROM Employees GROUP BY Dep_number ) AS A
Пишет ошибку:
Сообщение 8120, уровень 16, состояние 1, строка 3
Столбец «A. Dep_number» недопустим в списке выбора, поскольку он не содержится ни в статистической функции, ни в предложении GROUP BY.
Подскажите как быть?
- sql
- sql-server
- sql-server-2008
Вообще, группировка должна быть в том запросе, в котором используется аггрегация. Так что запрос будет таким:
SELECT A.Dep_number, MAX(A.SUM_Money) FROM ( SELECT Dep_number, SUM(Cash_bonus + Salary) AS SUM_Money FROM Employees GROUP BY Dep_number ) AS A GROUP BY A.Dep_Number.
Но это не то, что нам нужно, поскольку для каждого Dep_Number у нас в запросе только одна запись.
Можно просто отсортировать по SUM_Money по убыванию и взять первую запись:
SELECT TOP 1 A.Dep_number, A.SUM_Money FROM ( SELECT Dep_number, SUM(Cash_bonus + Salary) AS SUM_Money FROM Employees GROUP BY Dep_number ) AS A ORDER BY A.SUM_Money DESC
Но отделов с одинаковой суммой может быть несколько. Поэтому добавим ранжирование в подзапрос:
SELECT A. Dep_number, A.SUM_Money FROM ( SELECT rank() over(order by sum(cash_bonus+Salary) desc) rank, Dep_number, SUM(Cash_bonus + Salary) AS SUM_Money FROM Employees GROUP BY Dep_number ) AS A where rank=1
фиддл
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
SQL-Урок 11.
Выборка уникальных данных (SELECT DISTINCT)
Базы данных
Оператор SQL DISTINCT используется для указания на то, что следует работать только с уникальными значениями столбца.
Оператор SQL DISTINCT нашел широкое применение в операторе SQL SELECT, для выборки уникальных значений. Так же используется в агрегатных функциях.
Синтаксис
При выборке:
SELECT DISTINCT поле FROM имя_таблицы WHERE условие
При подсчете:
SELECT COUNT(DISTINCT поле) FROM имя_таблицы WHERE условие
При суммировании:
SELECT SUM(DISTINCT поле) FROM имя_таблицы WHERE условие
Примеры
Все примеры будут по этой таблице workers, если не сказано иное:
id | name | age | salary |
---|---|---|---|
1 | Дима | 23 | 400 |
2 | Петя | 25 | 500 |
3 | Вася | 23 | 500 |
4 | Коля | 30 | 1000 |
5 | Иван | 27 | 500 |
6 | Кирилл | 28 | 1000 |
Пример
Давайте выберем все уникальные значения зарплат из таблицы workers:
SELECT DISTINCT salary FROM workers
SQL запрос выберет следующие строки:
salary |
---|
400 |
500 |
1000 |
Пример
Давайте подсчитаем все уникальные значения зарплат из таблицы workers (их будет 3 штуки: 400, 500 и 1000):
SELECT COUNT(DISTINCT salary) as count FROM workers
SQL запрос выберет следующие строки:
count |
---|
3 |
Пример
Давайте подсчитаем одновременно все уникальные значения зарплат и уникальные значения возрастов и запишем их в разные поля:
SELECT COUNT(DISTINCT salary) as salary_count, COUNT(DISTINCT age) as age_count FROM workers
SQL запрос выберет следующие строки:
salary_count | age_count |
---|---|
3 | 5 |
Пример
Давайте просуммируем все уникальные значения зарплат из таблицы workers:
SELECT SUM(DISTINCT salary) as sum FROM workers
SQL запрос выберет следующие строки:
sum |
---|
1900 |
Вложенный оператор select в SQL Server
спросил
Изменено
7 месяцев назад
Просмотрено
949 тысяч раз
Почему не работает следующее?
ВЫБЕРИТЕ имя ИЗ (ВЫБЕРИТЕ имя ИЗ информации об агенте)
Думаю, мое понимание SQL неверно, потому что я думал, что это вернет то же самое, что и
ВЫБЕРИТЕ имя ИЗ информации об агенте
Разве внутренний оператор select не создает результирующий набор, который затем запрашивает внешний оператор SELECT?
- sql
- sql-сервер
- вложенный
- подзапрос
- запрос
Вам нужно псевдоним подзапроса.
ВЫБЕРИТЕ имя ИЗ (ВЫБЕРИТЕ имя ИЗ информации об агенте) a
или, чтобы быть более точным,
SELECT a.name FROM (SELECT name FROM agentinformation) a
4
Ответ Джо Стефанелли уже верен.
ВЫБЕРИТЕ имя ИЗ (ВЫБЕРИТЕ имя ИЗ информации об агенте) как
Нам нужно создать псевдоним подзапроса, потому что для запроса требуется табличный объект, который мы получим, создав псевдоним для подзапроса. Концептуально результаты подзапроса подставляются во внешний запрос. Поскольку нам нужен объект таблицы во внешнем запросе, нам нужно создать псевдоним внутреннего запроса.
Операторы, включающие подзапрос, обычно принимают одну из следующих форм:
- WHERE выражение [NOT] IN (подзапрос)
- ГДЕ выражение оператор сравнения_[ЛЮБОЙ | ВСЕ] (подзапрос)
- ГДЕ [НЕ] СУЩЕСТВУЕТ (подзапрос)
Проверьте дополнительные правила и типы подзапросов.
Дополнительные примеры вложенных подзапросов.
IN / NOT IN — этот оператор берет выходные данные внутреннего запроса после выполнения внутреннего запроса, которые могут содержать ноль или более значений, и отправляет их во внешний запрос. Затем внешний запрос извлекает все совпадающие строки [оператор IN] или не совпадающие строки [оператор NOT IN].
ЛЮБОЙ — [> ЛЮБОЙ или ЛЮБОЙ оператор берет список значений, созданных внутренним запросом, и извлекает все значения, которые больше минимального значения списка.
напр. >ANY(100,200,300), оператор ANY извлечет все значения больше 100.
- ALL – [>ALL или ALL оператор берет список значений, созданных внутренним запросом, и извлекает все значения, которые больше максимального списка.
напр. >ALL(100,200,300), оператор ALL выберет все значения больше 300.
- EXISTS – Ключевое слово EXISTS создает логическое значение [ИСТИНА/ЛОЖЬ]. EXISTS проверяет наличие строк, возвращаемых подзапросом.
0
ПОПРОБУЙТЕ ЭТО
'выберите *,(ВЫБЕРИТЕ количество (id) ИЗ продуктов, ГДЕ user_id = users.id) как products_count от пользователей ORDER BY products_count DESC, ID DESC LIMIT 200
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Требуется, но никогда не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
сервер sql — выбор SQL из запроса на выборку
Я хочу сделать запрос на выбор, который выполняет первый выбор, а затем использует этот выбор для выполнения второго выбора.
Я сделал 1-ю версию, используя временную таблицу, но хотел бы знать, есть ли способ сделать это без временной таблицы
мой код с временной таблицей выглядит так:
select dvd_name, book_name, count(*) nb в #t из США книга внутреннего соединения на usr_book_id = book_id внутреннее соединение dvd на dvd_id = usr_dvd_id сгруппировать по dvd_name, book_name имея количество (*)> 1 выберите 10 лучших usr_smthg, #t.book_name,dvd_name от #т книга внутреннего соединения b на b.book_name = #t.book_name внутреннее соединение usr на usr_book_id = book_id
- sql
- sql-server
Вы можете использовать CTE для этого
с т как ( выберите dvd_name, book_name, count(*) nb из США книга внутреннего соединения на usr_book_id = book_id внутреннее соединение dvd на dvd_id = usr_dvd_id сгруппировать по dvd_name, book_name имея количество (*)> 1 ) выберите 10 лучших usr_smthg, t.book_name,dvd_name от т книга внутреннего соединения b на b. book_name = t.book_name внутреннее соединение usr на usr_book_id = book_id
4
В sql вы можете использовать подзапрос, например:
выберите 10 лучших usr.usr_smthg, t.book_name, usr.dvd_name от ( выберите dvd_name, book_name, count(*) nb из США книга внутреннего соединения на usr_book_id = book_id внутреннее соединение dvd на dvd_id = usr_dvd_id сгруппировать по dvd_name, book_name имея количество (*)> 1 ) т книга внутреннего соединения b на b.book_name = t.book_name внутреннее соединение usr на usr_book_id = book_id -- предполагать заказать по убыванию n.n.b.
Вы можете использовать оконную функцию с подзапросом:
select top (10) t.usr_smthg, t.book_name, t.dvd_name из (выберите usr_smthg, book_name, dvd_name, count(*) over (раздел по dvd_name, book_name) как cnt из внутреннего соединения usr книга on usr_book_id = внутреннее соединение book_id DVD на dvd_id = usr_dvd_id ) т где снт > 1 Сортировать по ??;
??
указывает столбец заказа на основе того, что вы хотите верхних (10)
записей.