在大表SQL中具有最大值的子查询

时间:2014-08-04 13:40:42

标签: mysql sql

我试图查询以获取某人的上次工作经历的日期以及他们离开公司的日期(在某些情况下,该值为空,因为此人仍在该公司工作)

我有类似的东西:

  SELECT r.idcurriculum, r.startdate, r.lastdate FROM (
            SELECT idcurriculum, max(startdate) as startdate
            FROM workexperience
           GROUP BY idcurriculum) as s 
       INNER JOIN workexperience r on (r.idcurriculum = s.idcurriculum)

结构应该是这样的:

idcurriculum | startdate | lastdate

1234         | 2010-05-01| null
2532         | 2005-10-01| 2010-02-28
5234         | 2011-07-01| 2013-10-31
1025         | 2012-04-01| 2014-03-31

我尝试运行该查询,但我不得不停止它,因为它花了太长时间。 workexperience 表格权重为20GB。我不知道查询是否错误,我只运行了10分钟。

非常感谢帮助。

2 个答案:

答案 0 :(得分:1)

您可以尝试将查询重新表述为:

select r.*
from workexperience we
where not exists (select 1
                  from workexperience we2
                  where we2.idcurriculum = we.idcurriculum and
                        we2.startdate > we.startdate
                 );

重要提示:出于性能原因,您需要idcurriculum上的综合索引,startdate

create index idx_workexperience_idcurriculum_startdate on workexperience(idcurriculum, strtdate)

查询的逻辑是:“从workexperience获取所有行,其中idcurriculum具有较大startdate”的行没有行。这是一种说“让我最大化”的奇特方式。

使用group by,MySQL必须进行聚合,这通常涉及对数据进行排序 - 昂贵的20 GB。使用此方法,它可以使用索引查找结果,该索引应该更快。

答案 1 :(得分:0)

作为戈登答案的替代方案,您还可以将查询编写为:

    SELECT r.*
      FROM work_experience we
 LEFT JOIN work_experience we2
        ON we2.idcurriculum = we.idcurriculum
       AND we2.startdate > we.startdate
     WHERE we2.idcurriculum IS NULL;

但是当组中有多个最大start_dates时,您可能会遇到问题。