2010-08-31 47 views
1

給用戶我有一個表定義爲:最近一行在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

回答

1

在第二個例子中,你正在使用相關子查詢。您可以使用不相關的子查詢(派生表)。如果您碰巧列出所有的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瞭解更多關於此的提示。

2

你的第二個解決方案將工作,但性能可能不是最佳的,它可能會返回多行。你也應該改變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取得不俗的表現。

2

選擇最近的一排爲每個用戶(其中​​有事件)

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

0

這裏是你會怎麼做:

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