Oracle vs MySQL - 聚合函数

Mik*_*ike 1 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
Run Code Online (Sandbox Code Playgroud)

是因为Oracle不知道如何处理该order_datetime列?它不能像从GROUP BY order1.user_idMySQL中那样从行中接收到哪一行返回列结果吗?

编辑:

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

Tar*_*ryn 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
Run Code Online (Sandbox Code Playgroud)

MySQL使用a 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
Run Code Online (Sandbox Code Playgroud)

这适用于聚合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
Run Code Online (Sandbox Code Playgroud)

或者可以使用子查询重写.

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
Run Code Online (Sandbox Code Playgroud)

  • @Mike,您可以使用聚合函数,例如MIN(order1.order_datetime)来指示您想要第一个日期时间.不幸的是,询问项目组是不正确的,而不是指定决定如何选择组属性的聚合.如果您有男女团体,那么询问男性群体的年龄和女性群体的年龄是不正确的,您可能需要平均值,最小值或最大值,或总量,但是这个群体的"年龄"毫无意义. (6认同)
  • @LuisSiquot它也取决于OP(顺便接受答案)*测试*查询并确保它返回预期结果.不知道你为什么要责备bluefeet. (3认同)
  • @LuisSiquot我在这个问题中没有看到任何关于迁移的提及.虽然这是合理的,但我们不知道.我只看到***"任何人都可以解释甲骨文迄今为止的局限性......"***.答案很好地解释了这不是Oracle的限制,而是MySQL扩展在未正确使用时行为不当.那么,为什么有人建议复制一个行为不端的查询的查询(一个可能返回错误的查询或最好的半随机结果)? (3认同)
  • @LuisSiquot - 我不是在迁移.我只是试图理解差异(或者用你的话来说,"尊重问题"),因为我在一个使用两个数据库的环境中工作.blufeet不仅"解决了错误",他还解释了MySQL和Oracle的GROUP BY之间的区别. (3认同)
  • @LuisSiquot我认为非常清楚第一个查询"解决了错误"而应该使用其他版本.那么,答案的问题可能与此问题一样完整吗? (2认同)