使用SQL跟踪/查询状态更改

时间:2009-03-16 14:53:17

标签: sql-server linq tsql

我获得了一个数据库设计,它存储有关组织的信息以及组织发生或将要发生的任何变化。由于几乎任何组织都可以改变,因此有一个表只包含名为“组织”的表中的唯一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 ...

E.G。 组织可能只包含两行,只能分别保存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?”的问题。

同样可以回答第一个问题的类似问题是:如何显示每个组织的位置变化(简单),同时显示他们正在移动的PREVIOUS位置(很难?)?

注意:包含LINQ标签,以防在LINQ中有一个简单的方法,我可以走那条路。

1 个答案:

答案 0 :(得分: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

UNIQUE INDEX(organization_id, eff_date)会对您有所帮助。