2017-03-03 88 views
0

我有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' 

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

回答

4

您可以找到使用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

请注意,这个解决方案的规模不佳 – Strawberry

+0

@Strawberry - 我已经添加了一个链接到示例,该解决方案的其他两个替代方案也。 – GurV

+0

更慢?几乎不! – Strawberry

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' 
1

最有效的方式来获得这些报告将是创建在Car_Table一个额外的列last_history_id。每次将记录插入到History_Table时,触发器都会更新Car_Table中的last_history_id列。它会减少选择所需数据集的读取延迟,但在某些情况下,如果一次执行许多更新,这可能是一个窍门。

相关问题