【问题标题】:groupwise max causes sql_mode errorgroupwise max 导致 sql_mode 错误
【发布时间】:2017-08-03 14:04:05
【问题描述】:

挑战是从表格中选择每日最高温度以及每个日期和时间信息。

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

这会导致

SELECT 列表的表达式 #1 不在 GROUP BY 子句中,并且包含 非聚合列 'Weather.datesamp' 不是 功能上依赖于 GROUP BY 子句中的列;这是 与 sql_mode=only_full_group_by 不兼容

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

【问题讨论】:

  • 你想如何处理领带?因此,如果一个日期戳在同一天有 10 条记录,其中 4 条具有相同的温度,你想要所有 4 个日期戳吗?只有一个?如果是哪一个?

标签: mysql


【解决方案1】:

RDBMS 在基于集合的逻辑上效果最好。所以从两组的角度来考虑数据:

  • w2:一组包含给定日期的最高温度的数据
  • w:包含一段时间内所有测量值的数据域

通过加入这两个集合,我们可以只从 w 获得给定日期的最高温度的数据。

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

这假设:

  • 如果最高温度在同一日期的多条记录上,您希望全部记录,因为您没有说明如何处理关系。
  • 日期戳有时间分量;这是您希望查看的最高温度的日期/时间。

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

  • date(datesamp) 只返回日期/时间的日期部分。
  • max() 返回指定组的最高温度(在本例中为日期戳日期)

.

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 引擎(我能想到的);但并非在所有情况下都是最有效的。

【讨论】:

  • 感谢您提供有条理和周到的回复。识别假设尤其具有启发性。效果很好!
【解决方案2】:

你的sql模式是full group by。这意味着 select 中的所有列都必须在 Group By 子句中 日期戳在 select 但不在 group by 中。 但是对于 temp,由于您使用的是聚合函数 MAX,因此它不必在 GROUP BY 中。 在 group by 中使用 datestamp 或更改您的 sql 模式。

确切的原因是mysql full group by模式和mysql中语句的逻辑查询执行顺序

逻辑顺序

  • 来自
  • 在哪里
  • 分组依据
  • 聚合
  • 有
  • 选择

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

【讨论】:

  • 您对语句逻辑顺序的解释很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 2018-03-12
  • 2016-10-18
相关资源
最近更新 更多