Ms sql select в select: SELECT (Transact-SQL) — SQL Server
Содержание
Не получается сделать SELECT FROM SELECT [MS SQL Server]
Есть таблица Сотрудники (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 запрос?
Вопрос задан
Изменён
1 год 3 месяца назад
Просмотрен
2k раза
Нужно написать SQL запрос, который бы возвращал точно такой вывод:
id| --- 1 | 2 | 3 | 5 |
Представьте, что в БД нет ни одной таблицы, и создавать их нельзя.
mysql> SELECT 1 id UNION SELECT 2 id UNION SELECT 3 id UNION SELECT 5 id; +----+ | id | +----+ | 1 | | 2 | | 3 | | 5 | +----+ 4 rows in set (0,00 sec)
Существует ли более элегантное решение?
7
В MySQL единственный вариант (Алиас нужен только у первого числа):
select 1 ID union select 2 union select 3 union select 5
Самый красивый (для малого количества чисел) вариант можно написать в MS-SQL и Postrgess:
select * from (values (1),(2),(3),(5)) as t(id)
Oracle (С использованием системного типа в качестве коллекции):
select column_value ID from table(sys.odcinumberlist(1,2,3,5))
Если чисел значительно больше и они идут просто подряд, то почти универсальный (Из широко распространенных СУБД НЕ работает только в MySQL):
with Q as ( select 1 ID union all select ID+1 from Q where ID<5 ) select * from Q
Самый лаконичный (IMHO) вариант для большого количества чисел подряд в Oracle:
select rownum id from DUAL connect by rownum<6
Есть такой вариант, используя T-SQL. Физически таблица не создается, так что условие выполнено) Плюс это решение намного более гибкое, если вдруг кто-то решит изменить задачу.
declare @t1 as table(ID int) declare @i int=0 while (@i<5) begin set @i+=1 if (@i<>4) insert into @t1 values(@i) end select * from @t1
1
В Oracle ещё можно воспользоваться XQuery последовательностью:
select to_number(column_value) id from xmlTable ('1 to 3, 5') / ID ---------- 1 2 3 5
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
Вложенный оператор select в SQL Server
спросил
Изменено
2 месяца назад
Просмотрено
906 тысяч раз
484
Новинка! Сохраняйте вопросы или ответы и организуйте свой любимый контент.
Узнать больше.
Почему не работает следующее?
ВЫБЕРИТЕ имя ИЗ (ВЫБЕРИТЕ имя ИЗ информации об агенте)
Я думаю, я неправильно понимаю SQL, потому что я думал, что это вернет то же самое, что и
SELECT name FROM agentinformation
Разве внутренний оператор select не создает результирующий набор, который затем запрашивает внешний оператор SELECT?
- sql
- sql-сервер
- вложенный
- подзапрос
- запрос
Вам нужно указать псевдоним подзапроса.
ВЫБЕРИТЕ имя ИЗ (ВЫБЕРИТЕ имя ИЗ информации об агенте) a
или, чтобы быть более точным,
SELECT a.name FROM (SELECT name FROM agentinformation) a
4
Ответ Джо Стефанелли уже верен.
ВЫБЕРИТЕ имя ИЗ (ВЫБРАТЬ имя ИЗ информации об агенте) как
Нам нужно создать псевдоним подзапроса, потому что для запроса требуется табличный объект, который мы получим, создав псевдоним для подзапроса. Концептуально результаты подзапроса подставляются во внешний запрос. Поскольку нам нужен объект таблицы во внешнем запросе, нам нужно создать псевдоним внутреннего запроса.
Операторы, включающие подзапрос, обычно принимают одну из следующих форм:
- ГДЕ выражение [НЕ] В (подзапрос)
- ГДЕ выражение оператор сравнения_[ЛЮБОЙ | ВСЕ] (подзапрос)
- ГДЕ [НЕ] СУЩЕСТВУЕТ (подзапрос)
Проверьте дополнительные правила и типы подзапросов.
Дополнительные примеры вложенных подзапросов.
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 server — выбор SQL из запроса выбора
спросил
Изменено
3 года, 7 месяцев назад
Просмотрено
17 тысяч раз
2
Новинка! Сохраняйте вопросы или ответы и организуйте свой любимый контент.
Узнать больше.
Я хочу сделать запрос на выбор, который выполняет первый выбор, а затем использует этот выбор для выполнения второго выбора.
Я сделал 1-ю версию, используя временную таблицу, но я хотел бы знать, есть ли способ сделать это без временной таблицы
мой код с временной таблицей выглядит так:
выберите 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 для этого
с t as ( выберите 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 Сортировать по ??;
??
указывает столбец заказа в зависимости от того, что вы хотите top (10)
записи.