这似乎应该相对(没有双关语)容易做,但我无法理解它。我有三张桌子,以多对多的关系加入。主要问题"问题"表,"状态" table(查找表,指示不同状态的名称/描述:'打开','进行中','已关闭'等),以及中间&# 34; IssuesStatuses"表格允许主要"问题"记录。我尝试根据IssuesStatuses表中最新的相关记录编写T-SQL以获取"问题"列表以及最新的StatusName。这是表格的样子:
[问题]表:
- IssueID(PK)
- 问题名称
- IssueDescription
等
[IssuesStatuses]表:
- IssuesStatusesID(PK)
- IssueID(FK)
- StatusID(FK)
- IssuesStatusDate
[状态]表:
- StatusID(PK)
- StatusName
用户将在IssueStatuses表中添加多条记录(对于相同的IssueID),因为它们会更新主要问题记录的状态。因此,此查询应获取[Issues]记录,[IssuesStatuses]表中此记录的最新状态,以及[Status]表中与该IssuesStartuses记录关联的关联StatusName记录。我非常确定我需要子查询和/或Max(StatusDate)函数,但是当我在SQL中尝试这种函数时,我开始编写过于复杂的嵌套子查询。
这有意义吗?有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
这种状态被称为缓慢变化的维度。解决这些问题的一种方法是拥有一个有效的"和"结束"记录日期。使用EffDate
和EndDate
,您想要的查询非常简单:
select *
from IssueStatus ist
where EndDate is NULL
或
where EndDate = '9999-01-01' -- or whatever your far out future date is
缺点是插入新状态需要两个步骤:
EndDate
您通常会将此逻辑封装在存储过程或触发器中。
根据您的数据结构,您可以使用not exists
:
select ist.*
from IssueStatus ist
where not exists (select 1
from IssueStatus ist2
where ist2.issueId = ist.issueId and
ist2.IssueStatusDate > ist.IssueStatusDate
)
逻辑是"从IssueStatus
获取所有行,其中给定的问题没有以后的状态日期。"这相当于说:"给我一个最大日期的行。"但出于某种原因,当IssueStatus(IssueId, IssueStatusDate)
上有索引时,数据库引擎将很好地优化此查询。