我获得了一个数据库设计,它存储有关组织的信息以及组织发生或将要发生的任何变化。由于几乎任何组织都可以改变,因此有一个表只包含名为“组织”的表中的唯一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中有一个简单的方法,我可以走那条路。
答案 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)
会对您有所帮助。