Oracle vs MySQL - 聚合函数

时间:2013-02-27 18:07:06

标签: mysql database oracle

任何人都能解释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也不需要)。

3 个答案:

答案 0 :(得分: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中使用它不能保证order1.order_datetime的值是什么,MySQL只选择一个值,结果可能是意外的。

您需要使用GROUP BY或汇总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

答案 1 :(得分:0)

在oracle中,如果您只想按一列分组而不是全部尝试,则需要在Select的{​​{1}}中指定所有列

group by

答案 2 :(得分:0)

请参阅我的相关问题here
当Oracle强制需要分组功能或按字段分组时,Mysql会为非分组功能/字段设置“任意”值

来自Mysql manual
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.