假设我有一张桌子"到来"当物品到达某个位置时记录。每一行对应一次到达事件。
arrivals
========
LocationId ItemId TimeStamp
------------------------------------------
a 1 2015-11-24 11:00 (item 1 arrived at 11:00 at location a)
a 2 2015-11-24 11:01 (item 2 arrived at 11:00 at location a)
b 1 2015-11-24 11:05 (item 1 left location a and arrived at b)
b 2 2015-11-24 11:06 (item 2 left location a and arrived at b)
是否有一条SQL语句可以告诉我哪些项目位于位置A的11:03,可能没有让SQL服务器瘫痪?
(这将包括在11:03之前到达位置A的所有物品,并且从那时起没有到达任何其他地方)
每个位置通常同时有大约30个项目,100个不同的位置,每小时每小时约1000个到达。
是否有任何设计选择可以简化此类查询,即使这意味着对数据库进行非规范化处理?
目前我甚至无法想象一个可以获取此信息的sql命令,而无需在自定义循环中遍历整个表。
答案 0 :(得分:2)
如果商品可以转到某个位置并返回
,我会使用DISTINCT
在location A
之前检查'2015-11-24 11:03'
上的每个项目
但在'2015-11-24 11:03'
SELECT DISTINCT ItemId
FROM arrivals lA -- location A
WHERE LocationId = 'A'
AND lA.TimeStamp < '2015-11-24 11:03'
AND NOT EXISTS (SELECT 1
FROM arrivals lX -- any other location
WHERE lX.LocationId <> lA.LocationId
AND lX.ItemId = lA.ItemId
AND lX.TimeStamp >= '2015-11-24 11:03'
)
注意:您可能需要仔细检查<
和>=
以符合您的需求
答案 1 :(得分:1)
如果您想知道在给定时间或更早时间到达该位置的所有物品,这应该可以解决问题:
SELECT distinct ItemId FROM arrivals WHERE LocationId = 'a' AND TimeStamp <= '2015-11-24 11:03'
编辑: 并考虑到这样的事实,即它到达之后可能会离开该位置,并且仍然在我们的时间戳之前我建议这个:
SELECT arrivals_prim.itemId FROM
(SELECT itemId, max("TimeStamp") as last_arrival
FROM arrivals
WEHRE
"TimeStamp" <= '2015-11-24 11:03'
and locationId = 'a'
GROUP BY itemId) arrivals_prim
LEFT JOIN (SELECT itemId, max("TimeStamp") as last_departure
FROM arrivals
WEHRE
"TimeStamp" < '2015-11-24 11:03'
and locationId <> 'a'
GROUP BY itemId) arrivals_bis
ON (arrivals_prim.itemId = arrivals_bis.itemId)
WEHRE last_departure is null or last_departure < last_arrival