假设你有下表(这里感兴趣的列是binid):
id datetime agid binid status
1 2013-02-01 11:03:49 0 25 1
2 2013-02-01 11:03:53 0 25 1
3 2013-02-01 11:04:21 0 26 1
4 2013-02-01 11:04:23 0 26 0
5 2013-03-01 11:04:26 0 25 0
6 2013-03-01 11:04:30 0 36 0
7 2013-03-01 11:04:34 0 36 1
8 2013-03-01 11:04:35 0 36 1
9 2013-03-01 11:04:36 0 36 1
10 2013-03-01 11:04:39 0 36 0
11 2013-03-01 11:04:41 0 36 1
13 2013-03-01 11:04:50 0 25 1
14 2013-03-01 11:04:53 0 26 1
15 2013-03-01 11:15:25 0 25 1
16 2013-03-01 11:15:30 0 25 0
17 2013-03-01 11:15:39 0 23 1
18 2013-03-01 11:15:43 0 26 1
如何提取在特定时间范围内发生的每个binid的最后一次出现?
这是我到目前为止所使用的:
SELECT * FROM ( reports ORDER BY datetime ASC )
WHERE datetime >= TIMESTAMP('2013-03-01')
GROUP BY binid
但它会返回第一次出现。如何返回每个唯一binid的最后一次出现?
答案 0 :(得分:8)
您应该使用子查询来获得结果:
select r1.*
from reports r1
inner join
(
select max(datetime) MaxDate, binid
from reports
WHERE datetime >= TIMESTAMP('2013-03-01')
group by binid
) r2
on r1.binid = r2.binid
and r1.datetime = r2.maxdate
WHERE r1.datetime >= TIMESTAMP('2013-03-01')
问题在于,当您在单个列上使用GROUP BY
时,MySQL可以为不在GROUP BY
中的其他列返回意外值。 (见MySQL Extensions to GROUP BY)。
来自MySQL文档:
MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。 ...您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的值。
答案 1 :(得分:3)
SELECT binid,
SUBSTRING_INDEX(GROUP_CONCAT(agid ORDER BY datetime DESC), ',', 1) AS agid,
SUBSTRING_INDEX(GROUP_CONCAT(status ORDER BY datetime DESC), ',', 1) AS status
FROM reports
WHERE datetime <= TIMESTAMP('2013-03-01')
GROUP BY binid;
答案 2 :(得分:0)
SELECT * FROM ( reports ORDER BY datetime DESC)
WHERE datetime >= TIMESTAMP('2013-03-01')
GROUP BY binid LIMIT 1
答案 3 :(得分:-3)
将ORDER BY ASC
更改为ORDER BY DESC
。应该做的伎俩。