题
假设我有两个表,一个用于对象记录,另一个用于有关这些对象的活动记录。
每次插入或更新对象时,我都会在此活动表中插入新记录。
以简单的方式告诉它,假设我在活动表中有四个字段; objectId,类型,状态和日期。
当一个对象即将更新时,我打算获取该对象的最后一个状态并查找更改。如果更新值和前一个值之间存在差异,我将使用新输入设置值,否则我将其设置为null。因此,例如在更新过程中,用户只更改对象的状态值,但保留类型值相同,因此我将插入一个新行,其类型为空值,状态为新值。
SELECT * FROM Activity; oid type status date ----------------------------------------- 1 0 1 2009.03.05 17:58:07 1 null 2 2009.03.06 07:00:00 1 1 null 2009.03.07 20:18:07 1 3 null 2009.03.08 07:00:00
所以我必须创建一个视图告诉我对象的当前状态,如
SELECT * FROM ObjectStateView Where oid = 1; oid type status date ----------------------------------------- 1 3 2 2009.03.08 07:00:00
我如何实现这个_?
解决方案
假设日期可用于查找最新记录:
CREATE VIEW foo
AS
SELECT
A.oid,
(SELECT TOP 1 type FROM Activity At WHERE At.OID = A.oid AND At.Date <= MAX(A.date) AND type IS NOT NULL),
(SELECT TOP 1 status FROM Activity Ast WHERE Ast.OID = A.oid AND Ast.Date <= MAX(A.date) AND status IS NOT NULL),
MAX(A.date) AS date
FROM
Activity A
GO
编辑:如果你想要一个JOIN(未经测试)
CREATE VIEW foo
AS
SELECT TOP 1
A.oid,
At.type,
Ast.status,
A.date
FROM
Activity A
LEFT JOIN
(SELECT TOP 1 oid, date, type FROM Activity WHERE type IS NOT NULL ORDER BY date DESC) At ON A.OID = At.oid
LEFT JOIN
(SELECT TOP 1 oid, date, status FROM Activity WHERE status IS NOT NULL ORDER BY date DESC) Ast ON A.OID = Ast.oid
ORDER BY date DESC
GO
之前应该添加这个:
它将呈指数级扩展,因为您必须在不同时间触摸表格。
更好的解决方案是保持“当前”状态。表并通过活动触发器维护它。
其他提示
您是否考虑过使用 MAX 功能?
select oid, type, status, MAX(date) as max_date
from ObjectStateView
where oid = 1
不确定为什么你想要那里的空值。您可以通过比较最新的条目来跟踪输入之间的变化。然后,对象的当前状态是表中的最新条目。您可以通过创建要跟踪更改的对象部分的哈希值并将其存储为额外列来确定对象是否已更改。
历史价值观
由于您跟踪更改,因此您可能希望历史性地查看对象的状态:
SELECT a.oid,
a.date,
a_type.type,
a_status.status
FROM Activity a
LEFT JOIN Activity a_type
ON a_type.oid = a.oid
AND a_type.date = (SELECT TOP 1 date FROM Activity WHERE oid = a.oid AND date <= a.date AND type IS NOT NULL ORDER BY date DESC)
LEFT JOIN Activity a_status
ON a_status.oid = a.oid
AND a_status.date = (SELECT TOP 1 date FROM Activity where oid = a.oid AND date <= a.date AND status IS NOT NULL ORDER BY date DESC)
将返回:
oid date type status
----------- ---------- ----------- -----------
1 2009-03-05 0 1
1 2009-03-06 0 2
1 2009-03-07 1 2
1 2009-03-08 3 2
效果考虑因素:
另一方面,如果你只有几个字段,并且表格很大,性能就会成为一个问题。在这种情况下,我还有意义将整个值存储/缓存到另一个表 MyDataHistory 中,该表将包含如上表所示的数据。然后使用通过oid和date过滤最新行(仅1行)的SQL视图来选择当前(最新)版本是微不足道的。
不隶属于 StackOverflow