2011-04-05 108 views
26

我有一个包含下列项目的数据库表:获取最后不同的记录集

id code value datetime timestamp 

在该表中唯一的值位于ID即主键。

我想根据日期时间值检索此表中最后一组不同的记录。例如,下面就让我们说是我的表

id code value datetime    timestamp 
1 1023 23.56 2011-04-05 14:54:52 1234223421 
2 1024 23.56 2011-04-05 14:55:52 1234223423 
3 1025 23.56 2011-04-05 14:56:52 1234223424 
4 1023 23.56 2011-04-05 14:57:52 1234223425 
5 1025 23.56 2011-04-05 14:58:52 1234223426 
6 1025 23.56 2011-04-05 14:59:52 1234223427 
7 1024 23.56 2011-04-05 15:00:12 1234223428 
8 1026 23.56 2011-04-05 15:01:14 1234223429 
9 1025 23.56 2011-04-05 15:02:22 1234223430 

我想与ID的4,7,8检索记录,和9,即最后一组具有鲜明的代码(基于时间值)的记录。我所强调的仅仅是我试图实现的一个例子,因为这张表最终将包含数百万条记录和数百个单独的代码值。

我可以用什么SQL语句来达到这个目的?我似乎无法完成一个单一的SQL语句。我的数据库是MySQL 5.

回答

50

这应该适合你。

SELECT * 
FROM [tableName] 
WHERE id IN (SELECT MAX(id) FROM [tableName] GROUP BY code) 

如果id为AUTO_INCREMENT,就没有必要担心这是更为昂贵的计算日期时间,因为最近的日期时间也将有最高的ID。

更新:从性能的角度来看,要确保有大量的记录处理时idcode列索引。如果id是主键,则这是内置的,但您可能需要添加非聚集索引,其中包括codeid

+1

+1为避免日期时间测试,如果自动增量...我冒昧地重新格式化答案。 – krtek 2011-04-05 15:16:53

+0

工程就像一个魅力!非常感谢。 – 2011-04-05 15:23:30

+1

@smdrager,非常不错...节省了我的时间。 – vissu 2012-07-18 13:39:55

0

我会尝试这样的事:

select * from table 
where id in (
    select id 
    from table 
    group by code 
    having datetime = max(datetime) 
) 

(免责声明:这不是测试)

如果有更大的日期时间该行也有较大的ID,由smdrager提出的解决方案更快。

5

试试这个:

SELECT * 
    FROM <YOUR_TABLE> 
WHERE (code, datetime, timestamp) IN 
(
    SELECT code, MAX(datetime), MAX(timestamp) 
    FROM <YOUR_TABLE> 
    GROUP BY code 
) 
+0

由于表有一个主键,所以你不必做这么复杂的where子句。看到我的答案。 – krtek 2011-04-05 15:20:01

+0

@Krtek:同意,但这需要假定id是自动增量。 – Chandu 2011-04-05 15:27:21

+0

根本不,smdrager的答案确实,我的子查询返回使用好的id,因为'有'子句 – krtek 2011-04-05 15:46:13

1

这是老的文章,但测试与大表@smdrager答案是非常缓慢的。我对此的修复是使用“内连接”而不是“在哪里”。

SELECT * 
FROM [tableName] as t1 
INNER JOIN (SELECT MAX(id) as id FROM [tableName] GROUP BY code) as t2 
ON t1.id = t2.id 

这工作真的很快。

+0

谢谢。下次我需要使用它时,我会尝试一下。 – 2017-06-02 21:58:14