获取到达表中某个位置的项目列表

时间:2015-11-24 14:14:48

标签: sql database select database-design sql-server-2012

假设我有一张桌子"到来"当物品到达某个位置时记录。每一行对应一次到达事件。

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命令,而无需在自定义循环中遍历整个表。

2 个答案:

答案 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