SQL中的GROUP BY /聚合函数混淆

时间:2011-01-06 05:00:18

标签: sql oracle

我需要一些帮助来理顺某些东西,我知道这是一个非常容易的简单问题,但它在SQL中稍微让我感到困惑。

此SQL查询在Oracle中抛出'not a GROUP BY expression'错误。我理解为什么,正如我所知,一旦按照元组的属性进行分组,我就再也无法访问任何其他属性了。

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”就会抛出错误吗?

5 个答案:

答案 0 :(得分:42)

在标准SQL(但不是MySQL)中,使用GROUP BY时,必须列出GROUP BY子句中不是聚合的所有结果列。因此,如果order_details有6列,那么您必须在GROUP BY子句中列出所有6列(按名称 - 您不能在GROUP BY或ORDER BY子句中使用*。) p>

你也可以这样做:

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,等等。)

答案 1 :(得分:0)

要使用group by子句,您必须提及select语句中的所有列到group by子句,而不是聚合函数中的列。

要执行此操作而不是group,您可以使用partition by子句,只能使用一个端口作为分区。

您也可以通过1

进行分区

答案 2 :(得分:0)

SELECT * 
FROM order_details 
GROUP BY order_no

在上面的查询中,您正在选择所有列,因为它会抛出错误,而不是像.. 为了避免你必须提到select语句中所有列必须在group by子句中的所有列。

 SELECT * 
    FROM order_details 
    GROUP BY order_no,order_details,etc

等它表示order_details表中的所有列。

答案 3 :(得分:0)

使用通用表表达式(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

答案 4 :(得分:0)

SQL的写入顺序与执行顺序不同。

通常,您将这样编写SQL:

SELECT
FROM
JOIN
WHERE
GROUP BY
HAVING
ORDER BY

在后台,SQL是这样执行的:

FROM
JOIN
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

为什么您需要将SELECT中的所有非聚合列都放在GROUP BY上,这是编程中自上而下的行为。您无法调用尚未声明的内容。

了解更多:https://sqlbolt.com/lesson/select_queries_order_of_execution