GROUP BY / путаница агрегатных функций в SQL - PullRequest
41 голосов
/ 06 января 2011

Мне нужно немного помочь, чтобы что-то исправить, я знаю, что это очень простой и легкий вопрос, но это немного сбивает меня с толку в 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» вызоветошибка?

Ответы [ 4 ]

43 голосов
/ 06 января 2011

В стандартном 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 и т. Д.)

0 голосов
/ 28 апреля 2019

используйте общее табличное выражение (CTE), чтобы избежать этой проблемы.

несколько CT также пригодятся, вставив случай, когда я использовал ... может быть полезным

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
0 голосов
/ 10 февраля 2016
SELECT * 
FROM order_details 
GROUP BY order_no

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

 SELECT * 
    FROM order_details 
    GROUP BY order_no,order_details,etc

и т. д. это означает, что все столбцы из таблицы order_details.

0 голосов
/ 31 декабря 2015

Чтобы использовать предложение group by, вы должны упомянуть все столбцы из оператора select в предложении group by, но не столбец из агрегатной функции.

Чтобы сделать это вместо группировки по группам, вы можете использовать раздел по предложениям, вы можете использовать только один порт для группировки по разделам.

Вы также можете сделать это как раздел на 1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...