oracle 聚合函数group,关于oracle:GROUP BY / SQL中的聚合函数混淆

我需要一些帮助来理顺一些问题,我知道这是一个非常简单的问题,但这在SQL中使我有些困惑。

此SQL查询在Oracle中引发"不是GROUP BY表达式"错误。 我知道为什么,因为我知道一旦按元组的属性进行分组,就无法再访问任何其他属性。

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"将引发错误?

在标准SQL(但不是MySQL)中,当您使用GROUP BY时,必须列出GROUP BY子句中未聚合的所有结果列。因此,如果order_details有6列,则必须在GROUP BY子句中列出所有6列(按名称-您不能在GROUP BY或ORDER 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,依此类推。)

好的,因此在执行GROUP BY之后,聚合函数仍可访问特定order_no的所有单个元组。也就是说,即使这些元组已通过order_no分组在一起,SUM函数仍可以访问每个元组的order_price属性。

@克里斯:是的,或多或少。您可以想到GROUP BY将表中的行分为几组;每个组在GROUP BY子句中列出的列具有相同的一组值。然后,聚合将在指定的任何列上进行操作,并根据组中的行计算聚合。然后,结果由每个组一行,包含GROUP BY列值以及关联的聚合。嗯...我希望那很清楚...

是的,据我所知,这完全清除了它。非常感谢乔纳森,也感谢其他回答的人!

@JonathanLeffler感谢您的解释。我在MySQL上长大,当我开始与Oracle一起工作时,我对Oracles GROUP BY愚蠢至极,因为它必须包含每一列。现在我了解到甲骨文并不愚蠢。这是正常的。它的MySQL只是试图变得不合标准。 :-)

@JonathanLeffler-不是您的答案,但是您在下面的第一条评论非常清楚。所有这些本身就清除了我从不完全了解SQL的内容。

FWIW,并不是只有MySQL不需要在GROUP BY子句中严格要求所有的SELECT列。 H2,PostgreSQL是另外两个不坚持的。

@NeilStockton还有SQLite,如果我没记错的话。

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

SELECT *

FROM order_details

GROUP BY order_no

在上面的查询中,您选择了所有列,因为它会引发错误,而不是按类似项进行分组。

为了避免您不得不提及所有列,无论在select语句中是哪个,所有列都必须在group by子句中。

SELECT *

FROM order_details

GROUP BY order_no,order_details,etc

等等,这意味着order_details表中的所有列。

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

为此,您可以使用partition by by子句来代替group by,而只能使用一个端口将其作为group by。

您也可以将其划分为1

您可以使用分区给出一些示例代码吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值