简而言之,我正在尝试按日期对数据集进行排序,然后按另一列进行分组,从而选择每个列的最新行。
查询:
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
示例表:
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-mode的情况下防止发生此错误。
在阅读了有关group by
和only_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
如果我们想为datetime
的每个不同值返回最新的name
,那么规范模式将是:
SELECT t.name
, MAX(t.datetime) AS latest_datetime
FROM requests t
GROUP
BY t.name
ORDER
BY ...
如果(name,datetime)
元组保证是唯一的,我们可以通过将上面的查询结果连接到表来检索具有最新时间的行
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)
元组不是唯一的,那么上面的查询可能会返回具有相同name
和datetime
值的多行。有处理方法;给定request表的定义,最简单的方法是将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 ...
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;