实现SQL多对多连接的最佳方法

时间:2012-05-03 00:20:09

标签: sql many-to-many

我有三个表,它们的相关列是:

tPerson
-> PersonID

tPersonStatusHistory
-> PersonStatusHistoryID
-> PersonID
-> StatusID
-> PersonStatusDate

Status
-> StatusID

我想存储一个人曾经拥有的所有状态的完整历史记录。但我也希望能够轻松访问当前状态。

查询以获取当前状态:

SELECT TOP 1 StatusID FROM tPersonStatusHistory 
WHERE PersonID = ? ORDER BY PersonStatusDate DESC

我想要的是一个查询,它将获取一个人员记录列表,其最新的StatusID作为查询中的一列。

我们尝试了以下方法:

  1. 将上述查询作为选择中的子查询包括在内。
  2. 将一个CurrentPersonStatusHistoryID列添加到tPerson表并使用调用用户定义函数的计算列维护它。
  3. 使用tPersonStatusHistory表上的触发器维护CurrentPersonStatusHistoryID列。
  4. 用于提取Person记录的查询使用率非常高,因此我不希望每次都要查找History表。触发器方法最接近我想要的,因为数据保存在Person表中,并且仅在进行更新时更改(通常不是经常进行比较)。

    我发现触发器难以维持,我宁愿远离它们。我还发现,在执行Insert-Select或涉及多个记录的Update查询时,触发器仅在第一个记录而不是其他记录上调用。

    我真正想要的是将一些逻辑放入CurrentPersonStatusHistoryID的列定义中,按Save并在没有我干预的情况下将其保留并在后台更新。

    鉴于多对多关系很常见,我想知道是否有其他人遇到过类似的情况,并且对最高性能,最好是最麻烦的实现方式有所了解。

1 个答案:

答案 0 :(得分:1)

另一种方法是使用类似下面的查询,也许作为视图。它将为您提供每个人的最新StatusID。

SELECT PersonID, StatusID
FROM (
    SELECT PersonID, StatusID,
        rank() OVER(PARTITION BY PersonID ORDER BY PersonStatusDate DESC) as rnk
    FROM tPersonStatusHistory
) A
WHERE rnk = 1

我不确定这是否满足您对性能的要求,但这是您可以研究的内容。