2010-10-26 96 views
3

这是我的表:如何避免子查询?

ID KEY VALUE 
1 alpha 100 
2 alpha 500 
3 alpha 22 
4 beta 60 
5 beta 10 

我想检索所有KEY -s他们最新值的列表(其中ID是其最大):

ID KEY  VALUE 
3 alpha 22 
5 beta 10 

在MySQL我正在使用这个查询,这是无效的:

SELECT temp.* FROM 
    (SELECT * FROM t ORDER BY id DESC) AS temp 
GROUP BY key 

是否有可能在这种情况下避免子查询?

回答

5

使用INNER JOIN加入您的最大ID。

SELECT t.* 
FROM t 
     INNER JOIN (
      SELECT ID = MAX(ID) 
      FROM t 
      GROUP BY 
        key 
     ) tm ON tm.ID = t.ID     

假设ID列被编入索引,这可能与其将要获得的一样快。

+0

MySQL将创建** **许多临时表,而在我的例子中有将只有一个。你确定你的SQL更快吗? – yegor256 2010-10-26 06:51:38

+1

我没有运行MySQL,但试用两个版本并比较两个计划以确定最佳解决方案应该不难。只使用5个ID的SQL Server,这两种解决方案的执行速度同样快。使用13个ID,LEFT JOIN解决方案占55%,INNER JOIN解决方案占45%。当你的表增长时,你可以预期这种差异会变得更加明显。 *注意:ID列是主键,值列上有一个索引* – 2010-10-26 07:45:17

+0

...应该读*“键列上有一个索引”* – 2010-10-26 07:57:47

3

这里是the mysql documentation page that discusses this topic

它提出了三个不同的选项。

,不涉及一个子查询中只有一个是:

SELECT t1.id, t1.k, t1.value 
FROM t t1 
LEFT JOIN t t2 ON t1.k = t2.k AND t1.id < t2.id 
WHERE t2.k IS NULL; 
+0

这正是我所期待的,谢谢! – yegor256 2010-10-26 07:14:45

+0

糟糕,这个查询速度比我原来的慢10倍(我的表格中有2毫米行)... – yegor256 2010-10-26 07:55:46

+1

:-)原来的问题是“如何避免子查询”......不是“如何使最有效的查询“。我相信选择使用哪个查询来获得最佳性能取决于您在表中有多少行,以及'key'有多少个唯一值。很高兴你把它整理出来。 – Lee 2010-10-26 08:35:18