【问题标题】:Tracking/Querying Status Changes using SQL使用 SQL 跟踪/查询状态更改
【发布时间】:2009-03-16 14:53:17
【问题描述】:

我得到了一个数据库设计,它存储有关组织的信息以及组织已经发生或将要发生的任何更改。由于几乎任何关于组织的事情都可能发生变化,因此有一个表只包含名为“Organizations”的表中的唯一 OrganizationID。对该组织的更改都具有生效日期并遵循类似的设计模式,例如位置更改:

Table: organization_locations

organization_id (int, not null) - Relates back to the Organizations.ID column.
location_id (int, not null) - Relates to Locations.ID
eff_date (datetime, not null) - The date this change becomes effective

Table: Locations

ID (int, pk, identity, not null) - ID of the location
Name (varchar(255), not null) - Name of the location
... Other miscellaneous columns that aren't important for this discussion ...

例如 组织可能只包含两行,它们分别简单地保存 id 的 1 和 2。 位置可能有 3 个位置(id, name):

1, Location1
2, Location2
3, Location3

organization_locations (organization_id, location_id, eff_date):

1, 1, 1/1/2000  <--- Organization 1 is starting at location 1
1, 2, 1/1/2010  <--- On 1/1/2010, organization 1 moves to location 2 (from location 1)
1, 3, 1/1/2011 <--- On 1/1/2011, organization 1 moves to location 3 (in this case from location 2)

我已经有一个大型且可能过于复杂的查询来指定日期并在给定时间返回组织状态,但我觉得可能有更简单的方法。但是,手头的问题如下:

从这个架构中,我如何回答诸如“在给定的时间范围内,哪些组织将从位置 1 移动到另一个位置以及哪些组织将从另一个位置移动到位置 1:date1 到 date2?”之类的问题?

一个类似的问题也可以回答第一个问题:如何查询每个组织的位置变化(简单),同时显示他们从以前的位置移动(困难?)?

注意:包括 LINQ 标记以防万一在 LINQ 中有一种简单的方法可以做到这一点。

【问题讨论】:

    标签: sql-server linq tsql


    【解决方案1】:

    到位置 1:

    SELECT  DISTINCT organization_id
    FROM    organization_locations ol
    WHERE   ol.eff_date BETWEEN @date1 AND @date2
            AND ol.location = 1
    

    从位置 1:

    SELECT  DISTINCT organization_id
    FROM    (
            SELECT organization_id,
                   (
                   SELECT  TOP 1 location_id
                   FROM    organization_locations oln
                   WHERE   oln.organization_id = ol.organization_id
                           AND oln.eff_date < ol.eff_date
                   ORDER BY
                           organization_id DESC, eff_date DESC
                   ) AS previous_location
            FROM   organization_locations ol
            WHERE  eff_date BETWEEN @date1 AND @date2
            ) olo
    WHERE   previous_location = 1
    

    显示以前的位置:

    SELECT ol.*,
           (
           SELECT  TOP 1 location_id
           FROM    organization_locations oln
           WHERE   oln.organization_id = ol.organization_id
                   AND oln.eff_date < ol.eff_date
                   AND location_id = 1
           ORDER BY
                   organization_id DESC, eff_date DESC
           ) AS previous_location
    FROM   organization_locations ol
    

    (organization_id, eff_date) 上有一个UNIQUE INDEX 对您有很大帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 1970-01-01
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      相关资源
      最近更新 更多