在 SQL 中搜索每个对象的最后已知更新
Search last known update for each object in SQL
我有2个table:一个存储对象(Object),另一个存储对象的状态更新(例如:NOT_DONE、BEING_MANUFACTURED、DONE)(对象状态更新):
database diagram
每次对象状态更改时,都会在 ObjectStateUpdate table 中添加一行,其中包含新状态和状态更改日期。
在我的应用程序中,我有一个用例,我想检索所有处于特定状态的对象(假设所有正在制造的对象)。
这是通过一个复杂的 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
)
我想在对象table中添加一个外键列"lastUpdateId"
来存储对象最后一次更新的id(每次我有一个新的更新我都会存储它标识对象)。
这可以通过用更高效的请求替换它来避免必须执行大的 SQL 请求,但我担心如果由于某种原因 "lastUpdateId" 不是最新的 ObjectStateUpdate table.
的数据
那么我应该将此列添加到对象 table 以提高性能还是应该保持这样以避免不一致?
如果我没听错,您可以使用 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)
上的索引。
我有2个table:一个存储对象(Object),另一个存储对象的状态更新(例如:NOT_DONE、BEING_MANUFACTURED、DONE)(对象状态更新): database diagram
每次对象状态更改时,都会在 ObjectStateUpdate table 中添加一行,其中包含新状态和状态更改日期。
在我的应用程序中,我有一个用例,我想检索所有处于特定状态的对象(假设所有正在制造的对象)。
这是通过一个复杂的 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
)
我想在对象table中添加一个外键列"lastUpdateId"
来存储对象最后一次更新的id(每次我有一个新的更新我都会存储它标识对象)。
这可以通过用更高效的请求替换它来避免必须执行大的 SQL 请求,但我担心如果由于某种原因 "lastUpdateId" 不是最新的 ObjectStateUpdate table.
的数据那么我应该将此列添加到对象 table 以提高性能还是应该保持这样以避免不一致?
如果我没听错,您可以使用 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)
上的索引。