最近一行在MySQL

最近一行在MySQL

问题描述:

给用户我有一个表定义为:最近一行在MySQL

create table Foo (
    X integer, 
    Y timestamp, 
    Z varchar(255), 
    primary key (X, Y) 
); 

对于给定的X我想找到最新的行。到目前为止,我已经提出了以下内容,但想知道是否有人知道哪些内容会表现得更好,或者只是“有趣”,比如对自己使用左连接(我无法工作)。

select * from Foo where X=1234 order by Y desc limit 0,1; 
select * from Foo where X=1234 and Y in (select max(Y) from Foo where X=1234); 

谢谢!

+0

为Y保证为每个用户唯一的列? – 2010-08-31 11:30:42

+0

两个主键在表中是不可能的 – Murugesh 2010-08-31 11:33:15

+0

@Mark Byers:尽管Y很可能是唯一的,但它不能保证,因为两个条目在理论上可能具有相同的时间戳。 – Scruffers 2010-08-31 11:37:39

在第二个例子中,你正在使用相关子查询。您可以使用不相关的子查询(派生表)。如果您碰巧列出所有的foos,这会更快,因为对于外部查询的每一行,必须调用一次相关子查询一次。

这是一个使用派生表的例子:

SELECT foo.* 
FROM foo 
JOIN (
      SELECT MAX(Y) max_time, X 
      FROM  foo 
      GROUP BY X 
     ) d_foo ON (d_foo.X = foo.X AND 
        d_foo.max_time = foo.Y); 

测试用例:

INSERT INTO foo VALUES (1, '2010-01-01 12:00:00', '1'); 
INSERT INTO foo VALUES (1, '2010-01-03 12:00:00', '2'); 
INSERT INTO foo VALUES (2, '2010-01-05 12:00:00', '3'); 
INSERT INTO foo VALUES (2, '2010-01-02 12:00:00', '4'); 
INSERT INTO foo VALUES (3, '2010-01-08 12:00:00', '5'); 
INSERT INTO foo VALUES (4, '2010-01-03 12:00:00', '6'); 
INSERT INTO foo VALUES (4, '2010-01-04 12:00:00', '7'); 

结果:

+---+---------------------+------+ 
| X | Y     | Z | 
+---+---------------------+------+ 
| 1 | 2010-01-03 12:00:00 | 2 | 
| 2 | 2010-01-05 12:00:00 | 3 | 
| 3 | 2010-01-08 12:00:00 | 5 | 
| 4 | 2010-01-04 12:00:00 | 7 | 
+---+---------------------+------+ 
4 rows in set (0.02 sec) 

不过,如果你总是会限制你的结果只有一个X,你的解决方案可能很好。查看@Mark Byers' answer了解更多关于此的提示。

你的第二个解决方案将工作,但性能可能不是最佳的,它可能会返回多行。你也应该改变IN=

SELECT * FROM Foo 
WHERE X = 1234 AND Y = (SELECT MAX(Y) FROM Foo WHERE X = 1234) 

我认为首先soluton更好:

SELECT * 
FROM Foo 
WHERE X = 1234 
ORDER BY Y DESC 
LIMIT 1 

X上添加一个索引,Y取得不俗的表现。

选择最近的一排为每个用户(其中​​有事件)

select * from events e 
    join (select UserId, Max(time) time from events group by userId) t 
    ON (e.userId = t.userid and e.time = t.time) 
+0

我不认为这工作正常。 'select userId,max(time)'可能返回一个与表中的主键不一致的值,即它可以给用户ID 1,用户2的最大时间。 – Scruffers 2010-08-31 11:47:45

+0

@Scruffers,主键'和'分组'相关吗? “时间”字段无论是否是主键的一部分都无关紧要。 – 2010-08-31 11:52:26

+0

我想我在阅读你的解决方案之前,先编辑它以包含'group by'。我认为现在有效。谢谢。 – Scruffers 2010-08-31 11:56:08

这里是你会怎么做:

SELECT * 
FROM foo INNER JOIN (SELECT `x`, MAX(`y`) AS `y` FROM foo GROUP BY `x`) AS foo2 ON foo.x = foo2.x AND foo.y = foo2.y