查询连接2个表并从其中一个表中仅保留1行

时间:2014-03-11 13:48:43

标签: mysql sql

我有2个表(item和item_historic),我正在查找保留最后item_historic行(最大日期)并将其加入项目表的查询。

项目

id_item     state_item
5560        complete
5570        removed

item_historic:

id_historic id_item     state_historic  date
2002        5560        declared        2011-01-13 13:32:15
2198        5560        complete        2011-03-14 11:44:40
1780        5570        declared        2011-03-15 15:26:55
2208        5570        removed         2011-04-15 08:17:59

结果:

id_item id_historic state_item      date                state_historic
5560    2198        complete        2011-03-14 11:44:40 complete
5570    2208        removed         2011-04-15 08:17:59 removed 

我只想要一个id_item。

我希望有意义并提前感谢。

编辑:错误的结果,我的问题是查询应该是什么样的? 试过:

select ah.id_item, ah.id_historic, at.state, date, ah.id_type, ah.state_item  from item at left join item_historic ah on ah.id_item = at.id_item group by ah.id_item order by max(date) ;

3 个答案:

答案 0 :(得分:1)

在MySQL中,not exists方法通常效率最高:

select ah.id_attestation, ah.id_historic, at.state, date, ah.id_type, ah.state_aft 
from `via-energica_plateforme`.attestation at left join
     `via-energica_plateforme`.attestation_historic ah
     on ah.id_attestation = at.id_attestation
where not exists (select 1
                  from `via-energica_plateforme`.attestation_historic ah2
                  where ah2.id_item = ah.id_item and
                        ah2.date > ah.date
                 );

此查询最适合attestation_historic(id_item, date)上的索引。

not exists子句需要在这种情况下习惯一些。它是说"选择ah中的行,其中表中没有最近的行" - 与#34相同;获得最大日期"。 MySQL的优势在于不需要聚合,聚合可能是一项昂贵的操作。但是,对于性能,你真的需要比较这两种方法。

答案 1 :(得分:0)

以下是使用子查询执行此操作的方法:

SELECT i.id_item, ih.id_historic, i.state_item, sq.max_date as `date`, ih.state_historic
FROM attestation i
    INNER JOIN (SELECT id_item, MAX(`date`) AS max_date FROM attestation_historic GROUP BY id_item) AS sq ON i.id_item = sq.id_item
    INNER JOIN attestation_historic ih ON i.id_item = ih.id_item AND sq.max_date = ih.`date`;

答案 2 :(得分:0)

也许有另一种方式,但这可行:

SELECT t.id_item, t.id_historic, i.state_item, t.date, t.state_historic FROM item i 
LEFT JOIN 
(SELECT * FROM (SELECT * 
FROM id_historic ORDER BY DATE DESC) t GROUP BY t.`id_item`
) t ON t.id_item = i.id_item ORDER BY t.date;