groupwise max导致sql_mode错误

时间:2017-08-03 14:04:06

标签: mysql

挑战在于从表格中选择每日最高温度以及每种温度的日期和时间信息。

SELECT datestamp, max(temp) hitemp from Weather w group by `year`, `month`, `day`;

这会导致

  

SELECT列表的表达式#1不在GROUP BY子句中并且包含   nonaggregated列'Weather.datestamp'不是   功能上依赖于GROUP BY子句中的列;这是   与sql_mode = only_full_group_by

不兼容

其他类似的问题建议使用JOIN,但我看不出如何使用JOIN语法,因为高温值不是唯一的。

2 个答案:

答案 0 :(得分:1)

你的sql模式是完全分组的。这意味着select中的所有列都必须在Group By子句中 datestamp在select中但不在group by中。 但是对于temp,因为你使用的是聚合函数MAX,所以它不需要在GROUP BY中。 在group by中使用datestamp或更改你的sql模式。

确切原因是mysql完全按模式分组和mysql语句的逻辑查询执行顺序

逻辑顺序

  • FROM
  • WHERE
  • GROUP BY
  • 聚合
  • HAVING
  • 选择

因此,GROUPING在SELECT之前完成。因此,如果选择了完整的分组依据,则SELECT可以单独访问GROUPED和AGGREGATED列。

答案 1 :(得分:1)

RDBMS最适合基于集合的逻辑。因此,请考虑两组数据:

  • w2:包含给定日期最大临时值的一组数据
  • w:包含一段时间内所有测量值的数据世界

通过连接这两组,我们可以获得w中具有给定日最高温度的数据。

通过对整个Universe集{w}使用内联视图{w2},我们可以生成每天的最大临时值,然后返回到基集{w}以获取每天的时间信息。最大温度

这假定:

  • 如果您想要同一日期的多个记录中有最大临时值,那么您并未指明如何处理关系。
  • datestamp有一个时间组件;它是您希望在一天中看到最高温度的日期/时间。

这是其他人最有可能加入的意思:

  • date(datestamp)只返回日期/时间的日期组件。
  • max()返回表示的组的最大临时值(在本例中为datestamp的日期)

SELECT datestamp, Temp
FROM weather W
INNER JOIN (SELECT date(datestamp) mDate, max(temp) as mtemp
            FROM weather
            GROUP BY  Date(DateStamp)) W2
  on W.temp = W2.mtemp
 and Date(w.Datestamp) = w2.mDate

附加信息: MySQL不支持cross apply,也不支持分析函数row_number() Over (partition by date(datestamp) order by temp desc),它们也可以用来解决这个问题,性能可能更高。 SQL Server,Oracle,DB2,Postgresql都有不同的解决方法;但是上面的例子适用于所有RDBMS引擎(我能想到);但在所有情况下都不是最有效的。