我需要一些帮助来理顺某些东西,我知道这是一个非常容易的简单问题,但它在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”就会抛出错误吗?
答案 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