Ошибка GROUP BY/агрегатная функция в SQL
Мне нужно немного помочь выправить что-то, я знаю, что это очень простой вопрос, но это что-то немного смущает меня в SQL.
Этот SQL-запрос выдает ошибку "не выражение GROUP BY" в Oracle. Я понимаю, почему, поскольку я знаю, что когда я группирую атрибут кортежа, я больше не могу получить доступ к любому другому атрибуту.
SELECT *
FROM order_details
GROUP BY order_no
Однако это работает
SELECT SUM(order_price)
FROM order_details
GROUP BY order_no
Просто для конкретного понимания этого вопроса.... Предполагая, что в каждом заказе есть несколько кортежей в order_details, как только я группирую кортежи в соответствии с order_no, я все равно могу получить доступ к атрибуту order_price для каждого отдельного кортежа в группе, но только с использованием агрегатной функции?
Другими словами, агрегированные функции, используемые в предложении SELECT, могут быть развернуты в группу, чтобы увидеть "скрытые" атрибуты, где просто использование "SELECT order_no" будет вызывать ошибку?
Ответы
Ответ 1
В стандартном SQL (но не в MySQL), когда вы используете GROUP BY, вы должны перечислить все столбцы результатов, которые не являются агрегатами в предложении GROUP BY. Итак, если order_details
имеет 6 столбцов, вы должны указать все 6 столбцов (по имени - вы не можете использовать *
в предложениях GROUP BY или ORDER BY) в предложении GROUP BY.
Вы также можете сделать:
SELECT order_no, SUM(order_price)
FROM order_details
GROUP BY order_no;
Это будет работать, потому что все неагрегатные столбцы перечислены в предложении GROUP BY.
Вы можете сделать что-то вроде:
SELECT order_no, order_price, MAX(order_item)
FROM order_details
GROUP BY order_no, order_price;
Этот запрос не имеет смысла (или, скорее всего, не имеет смысла), но он будет "работать". Он будет перечислять каждый отдельный номер заказа и цену заказа и будет указывать максимальный элемент (номер) заказа, связанный с этой ценой. Если все позиции в заказе имеют разные цены, вы получите группы по одной строке. OTOH, если в заказе есть несколько предметов по той же цене (скажем, 0,99 фунта стерлингов каждая), тогда она группирует их вместе и возвращает максимальный номер позиции заказа по этой цене. (Я предполагаю, что в таблице есть первичный ключ на (order_no, order_item)
, где первый элемент в заказе имеет order_item = 1
, второй элемент - 2 и т.д.)
Ответ 2
Чтобы использовать предложение group by, вы должны упомянуть обо всех столбцах из оператора select в разделе group by, но не в столбце из функции aggregate.
Чтобы сделать это вместо группы, вы можете использовать предложение partition by, вы можете использовать только один порт для группировки в виде раздела.
вы также можете сделать его как раздел на 1
Ответ 3
SELECT *
FROM order_details
GROUP BY order_no
В вышеприведенном запросе вы выбираете все столбцы из-за того, что он выбрасывает ошибку, а не группу чем-то вроде..
чтобы избежать упоминания всех столбцов в зависимости от того, что должно быть в инструкции select, все столбцы должны быть в разделе group by.
SELECT *
FROM order_details
GROUP BY order_no,order_details,etc
и т.д. это означает, что все столбцы из таблицы order_details.
Ответ 4
используйте общее табличное выражение (CTE), чтобы избежать этой проблемы.
несколько CTs также пригодятся, вставив случай, когда я использовал... может быть полезно
with ranked_cte1 as
( select r.mov_id,DENSE_RANK() over ( order by r.rev_stars desc )as rankked from ratings r ),
ranked_cte2 as ( select * from movie where mov_id=(select mov_id from ranked_cte1 where rankked=7 ) ) select * from ranked_cte2
select * from movie where mov_id=902