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

Ответ Джо Стефанелли уже верен.

 ВЫБЕРИТЕ имя ИЗ (ВЫБРАТЬ имя ИЗ информации об агенте) как
 

Нам нужно создать псевдоним подзапроса, потому что для запроса требуется табличный объект, который мы получим, создав псевдоним для подзапроса. Концептуально результаты подзапроса подставляются во внешний запрос. Поскольку нам нужен объект таблицы во внешнем запросе, нам нужно создать псевдоним внутреннего запроса.

Операторы, включающие подзапрос, обычно принимают одну из следующих форм:

  • ГДЕ выражение [НЕ] В (подзапрос)
  • ГДЕ выражение оператор сравнения_[ЛЮБОЙ | ВСЕ] (подзапрос)
  • ГДЕ [НЕ] СУЩЕСТВУЕТ (подзапрос)

Проверьте дополнительные правила и типы подзапросов.

Дополнительные примеры вложенных подзапросов.

  1. IN / NOT IN — этот оператор берет выходные данные внутреннего запроса после выполнения внутреннего запроса, которые могут содержать ноль или более значений, и отправляет их во внешний запрос. Затем внешний запрос извлекает все совпадающие строки [оператор IN] или не совпадающие строки [оператор NOT IN].

  2. ЛЮБОЙ – [>ЛЮБОЙ или ЛЮБОЙ оператор берет список значений, созданных внутренним запросом, и извлекает все значения, которые больше минимального значения списка.

напр. >ANY(100,200,300), оператор ANY извлечет все значения больше 100.

  1. ALL – оператор [>ALL или ALL берет список значений, созданных внутренним запросом, и извлекает все значения, которые больше максимального списка.

напр. >ALL(100,200,300), оператор ALL выберет все значения больше 300.

  1. 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) записи.