在SQL中搜索每个对象的最新已知更新

问题描述 投票:0回答:1

我有一个2表:一个存储对象(对象),其他存储对象状态(对象状态更新)的状态更新(例如:NOT_DONE,BEING_MANUFACTURED,DONE):database diagram

每次对象状态改变时,都会在ObjectStateUpdate表中添加一行,其中包含新的状态和状态改变的日期。

在我的应用程序中,有一个用例,我想检索处于特定状态的所有对象(假设所有正在制造的对象)。

这是通过一个复杂的SQL请求完成的,该请求根据更新的日期获取每个对象的最新已知更新,如果同时发生了两个更新,则我使用更新ID来查找最后一个(每个对象具有至少一个状态更新):

SELECT * 
FROM ObjectStateUpdate 
WHERE id =
(
    SELECT MAX(id) 
    FROM ObjectStateUpdate 
    INNER JOIN (
        SELECT objectId, MAX(date) AS max_date 
        FROM trade_manager_app_orderupdate GROUP BY objectId
    ) as Latest 
    ON ObjectStateUpdate.objectId = Latest.objectId 
    AND ObjectStateUpdate.date = Latest.max_date 
    GROUP BY ObjectStateUpdate.objectId
)

[我曾考虑在对象表中添加一个外键列"lastUpdateId"来存储对象的最新更新的ID(每次我有一个新更新时,我都会将其ID存储到该对象)。

这可以通过用效率更高的请求代替它来避免执行大型SQL请求,但是,如果出于某种原因,“ lastUpdateId”不能与数据库更新保持一致,恐怕它将在数据库模型中添加不一致的地方。 ObjectStateUpdate表的数据。

所以我应该将此列添加到对象表中以提高性能,还是应该像这样保持它以避免不一致?

sql database sqlite date greatest-n-per-group
1个回答
0
投票
如果我正确地遵循了您的说明,则可以使用row_number()大大简化现有查询(如果您的SQLite版本支持它们);

select * from ( select u.*, row_number() over(partition by objectId order by date desc, id desc) rn from ObjectStateUpdate u ) t where rn = 1 and state = 'BEING_MANUFACTURED'

您可以通过相关的子查询获得相同的结果:

您可以通过相关的子查询获得相同的结果:

select u.* from ObjectStateUpdate u where id = ( select u1.id from ObjectStateUpdate u1 where u1.objectId = u.objectId order by date desc, id desc limit 1 ) and state = 'BEING_MANUFACTURED'

为了提高性能,您需要在(objectId, date, id)上建立索引。 
© www.soinside.com 2019 - 2024. All rights reserved.