1

谁能解释 Oracle 的局限性,为什么以下语句在 MySQL 中有效,但在 Oracle 中收到“不是 GROUP BY 表达式”?

  SELECT order1.user_id, 
         order1.order_datetime, 
         SUM(order2.order_total)
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id
GROUP BY order1.user_id

是不是因为 Oracle 不知道如何处理该order_datetime列?GROUP BY order1.user_id它不能像在 MySQL 中那样只从它从行接收的任何行返回列结果吗?

编辑:

我知道所有列都应该在 group by 中,但是我试图理解为什么 Oracle 不会返回与 MySQL 类似的结果(而 MySQL 不需要每个 GROUP BY,而 Oracle 需要)。

4

3 回答 3

12

Oracle 实际上正在执行正确的行为。当您使用GROUP BY时,选择列表中的项目必须出现在GROUP BY或聚合函数中。

SELECT order1.user_id, 
         order1.order_datetime, 
         SUM(order2.order_total)
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id
GROUP BY order1.user_id, order1.order_datetime

MySQL 使用EXTENSION TO GROUP BY允许不强制执行FULL GROUP BY的行为。在 MySQL 中使用 this 并不能保证 的值是什么order1.order_datetime,MySQL 只是选择一个值,结果可能出乎意料。

您要么需要对列表GROUP BY中的所有项目使用 a 或聚合SELECT(类似于上面),要么必须重写查询。您可以使用以下任何一种:

SELECT order1.user_id, 
         min(order1.order_datetime) order_datetime, 
         SUM(order2.order_total)
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id
GROUP BY order1.user_id

它将聚合应用于order_datetime,那么您不必按日期分组。

您可以使用sum() over()

SELECT order1.user_id, 
         order1.order_datetime, 
         SUM(order2.order_total) over(partition by order1.user_id) order_total
FROM order_table order1 
JOIN order_table order2 ON order1.user_id = order2.user_id

或者这可以使用子查询重写。

SELECT order1.user_id, 
     order1.order_datetime, 
     order2.order_total
FROM order_table order1 
JOIN
(
    select SUM(order_total) order_total, user_id
    from order_table 
    group by user_id 
) order2
    ON order1.user_id = order2.user_id
于 2013-02-27T18:10:15.660 回答
0

在此处查看我的相关问题
Mysql 假定非分组函数/字段的“任何”值,而 Oracle 强制需要分组函数或按字段分组

来自Mysql 手册
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal in MySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.

于 2013-02-27T18:19:44.790 回答
0

在 oracle 中,需要指定 inSelect中的所有列group by,如果您只想按一列分组而不是全部尝试这个

SELECT order1.user_id, 
         order1.order_datetime, 
SUM(order2.order_total) OVER (PARTITION BY order1.user_id) order_total
    FROM order_table order1 
    JOIN order_table order2 ON order1.user_id = order2.user_id
于 2013-02-27T18:11:44.490 回答