最近一行在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);
谢谢!
答
在第二个例子中,你正在使用相关子查询。您可以使用不相关的子查询(派生表)。如果您碰巧列出所有的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)
答
这里是你会怎么做:
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
为Y保证为每个用户唯一的列? – 2010-08-31 11:30:42
两个主键在表中是不可能的 – Murugesh 2010-08-31 11:33:15
@Mark Byers:尽管Y很可能是唯一的,但它不能保证,因为两个条目在理论上可能具有相同的时间戳。 – Scruffers 2010-08-31 11:37:39