MySQL 5.7.25 group by sub-query and order by "nonaggregated column"错误

MySQL 5.7.25 group by sub-query and order by "nonaggregated column" error

简而言之,我正在尝试按日期排序日期集,然后按另一列分组,从而选择每列的最新行。

查询:

SELECT name, datetime
FROM (
    SELECT *
    FROM `requests`
    ORDER BY datetime
) a
GROUP BY a.name;

错误:

#1055 - Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'a.datetime' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

示例table:

CREATE TABLE `requests` (
 `id` int(8) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(10) DEFAULT NULL,
 `datetime` datetime DEFAULT CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

目标是防止此错误发生而无需更改默认 sql-模式

阅读了更多关于 group byonly_full_group_by 的内容后,我目前不明白为什么子查询会影响外部查询。

查询是按照

写的

如果没有像 sum() 或 min() 这样的聚合函数,您不应该使用 GROUP BY。

如果您想要不同的结果,请使用 DISTINCT

SELECT distinct name, datetime
FROM (
    SELECT *
    FROM `requests`
    ORDER BY datetime
) a

但是如果您需要单行作为名称,您应该为日期时间使用聚合函数,例如

SELECT  name, max(datetime)
FROM (
    SELECT *
    FROM `requests`
    ORDER BY datetime
) a
group by name

https://www.db-fiddle.com/f/b2EAh6UiVyEdNVbEKbUEcQ/0

SELECT r.name, r.datetime
FROM `requests` r
LEFT JOIN `requests` r2 
ON r.name = r2.name
   AND r.datetime < r2.datetime
WHERE r2.name IS NULL;

或者只是普通的 GROUP BY:

SELECT r.name, MAX(r.datetime)
FROM `requests` r
GROUP BY r.name;

如果我们想要 return 最新的 datetime 对于 name 的每个不同值,规范模式将是:

 SELECT t.name
      , MAX(t.datetime) AS latest_datetime 
   FROM requests t
  GROUP
     BY t.name
  ORDER
     BY ...

如果保证 (name,datetime) 元组是唯一的,我们可以通过将上面的查询结果连接回 table

来检索具有最新时间的行
 SELECT r.id
      , r.name
      , r.datetime
   FROM ( SELECT t.name
               , MAX(t.datetime) AS latest_datetime 
            FROM requests t
           GROUP
              BY t.name
        ) s
  JOIN requests r
    ON r.name     <=> s.name 
   AND r.datetime <=> s.latest_datetime
 ORDER
    BY ...

如果 (name,datetime) 元组不是唯一的,则上面的查询可能 return 多行具有相同值 namedatetime。有一些方法可以解决这个问题;鉴于请求 table 的定义,最简单的方法是将 id 列包装在聚合中,并在外部查询上添加 GROUP BY 子句 ...

 SELECT MIN(r.id)  AS id 
      , r.name
      , r.datetime
   FROM ( SELECT t.name
               , MAX(t.datetime) AS latest_datetime 
            FROM requests t
           GROUP
              BY t.name
        ) s
  JOIN requests r
    ON r.name     <=> s.name 
   AND r.datetime <=> s.latest_datetime
 GROUP
    BY r.name
     , r.datetime
 ORDER
    BY ...