如何在联接表中按日期选择最后一条记录

时间:2017-03-03 18:09:25

标签: mysql sql

我有2个表,Car_Table和History_Table。我希望能够在所有汽车的状态设置为已损坏时选择最后一个历史项目。

表格如下

Car_Table
Car_ID  Driver_Name Car_Status
1       Alan        Broken
2       Dave        Broken

History_Table
id  Date        Notes       Car_Id
1   01-01-2017  Change oil      1
2   02-01-2017  Check Brakes    1
3   02-01-2017  Service         2
3   03-01-2017  Cleaning        2

当我这样做时

select Car_Table.Driver_Name,History_Table.Notes from Car_Table 
inner join History_Table on Car_Table.Car_ID = History_Table.CarID 
where Car_Table.Car_Status = 'Broken'

我获得了所有返回的历史记录。有没有办法获得状态为“已损坏”的每辆车的最后一个历史项目?

3 个答案:

答案 0 :(得分:3)

您可以使用left join技术找到每辆车的最大日期行,然后将其加入Car_table:

select Car_Table.Driver_Name,
    History_Table.Notes
from Car_Table
inner join (
    select h1.*
    from History_Table h1
    left join History_Table h2 on h1.Car_ID = h2.Car_ID
        and h1.date < h2.date
    where h2.Car_ID is null
    ) History_Table on Car_Table.Car_ID = History_Table.CarID
where Car_Table.Car_Status = 'Broken';

请参阅官方MySQL站点以获取其他解决方案(使用相关和不相关子查询中的聚合,这可能比上述解决方案慢)。

答案 1 :(得分:1)

您可以使用子查询来获取最后一条记录。理想情况下,如果记录数量很大,“日期”字段应该有一个索引。

select Car_Table.Driver_Name,History_Table.Notes 
  from Car_Table 
  inner join History_Table on Car_Table.Car_ID = History_Table.CarID 
    and History_Table.id=(
      select History_Table2.id 
        from History_Table2 
        Where History_Table2.CarID=History_Table.CarID
        Order by date desc 
        Limit 1
    )
  where Car_Table.Car_Status = 'Broken'

答案 2 :(得分:1)

获得此类报告的最有效方法是在Car_Table中创建额外的列last_history_id。每次将记录插入History_Table触发器时,都会更新last_history_id中的Car_Table列。它会减少选择所需数据集的读取延迟,但如果一次执行许多更新,在某种程度上可能会成为一种技巧。