带日期计算的SQL视图

时间:2012-07-25 06:36:10

标签: sql

我有一个跟踪库存位置的数据库。

应用程序编写得很糟糕,并且是一堆没有MVC分离的意大利面条代码,模型的更新可能发生在任意数量的文件中。

首次编写应用程序时,只需跟踪库存当前所在的位置,因此库存表中存在一个SiteID列,列出当前已分配给它的列。

此后,所有者已决定要保留库存分配到哪个位置的历史记录。我没有遍历所有代码来尝试找到它可能更新的所有地方,而是在库存表中添加了一个触发器ON UPDATEON INSERT,用于记录历史表中的移动。

最初的要求是能够查看使用SELECT * FROM history WHERE InvID = X ORDER BY timestamp DESC

轻松解决的库存的移动历史记录

现在我被要求为给定位置生成一个列表,该列表显示何时为站点分配了一个库存,以及它离开的日期(例如下面的例子)。理想情况下,我希望在不修改现有架构和触发器的情况下实现此目的。

我能够检索在一个点分配给该站点的所有库存的清单以及分配给它的日期。我正在努力的是如何找到一块库存离开网站的日期。我可以在应用程序中完成它,但我想知道是否可以使用SQL。

广告资源表

InventoryID     InventoryName    SiteID
===========     =============    ======
          1     Widget A         $ID
          2     Widget B         $ID
          3     Widget C         $ID

地点信息表

SiteID    SiteName
======    ========
     1    Somewhere
     2    Nowhere
     3    Anywhere

历史记录表

InvID    SiteID    Timestamp
=====    ======    =========
    1         1    2012-01-01
    1         2    2012-01-02
    2         1    2012-01-03
    1         1    2012-01-04

新视图应如下所示

InvID    DateIn        DateOut
=====    ==========    ==========
    1    2012-01-01    2012-01-02
    2    2012-01-03    NULL
    1    2012-01-04    NULL   

使用编程语言生成表的Psuedo代码(后处理SQL查询

SELECT * FROM history WHERE SiteID = 1

foreach (row in result) {
    DateOut = SELECT * FROM history WHERE InvID = result.InvID AND timestamp > result.timestamp LIMIT 1
}

2 个答案:

答案 0 :(得分:1)

试试这个:

只需将左外连接到同一个表并从右表中取出最小日期

select H1.InvID,I.InventoryName,H1.SiteID,H1.[Timestamp] [date in],
MIN(H2.[Timestamp]) [date out] 
from    History H1 left outer join History H2
on      H1.InvID=H2.InvID and H1.[Timestamp]<H2.[Timestamp]
join Inventory I on I.InventoryID= H1.InvID
where   H1.SiteID=1
group by    H1.InvID,I.InventoryName,H1.SiteID,H1.[Timestamp]

Sql Fiddle demo

答案 1 :(得分:0)

您可以使用子查询查找清单项位于其他站点的第一个日期:

select  h1.InvID
,       h1.Timestamp as DateIn
,       (
        select  min(TimeStamp)
        from    history h2
        where   h2.InvID = h1.InvID
                and h2.SiteID <> h1.SiteID
                and h2.TimeStamp > h1.TimeStamp
        ) as DateOut
from    history h1
where   h1.SiteID = X