【问题标题】:T-SQL to get most recent related record in many to many tablesT-SQL 获取多对多表中的最新相关记录
【发布时间】:2014-03-18 22:48:53
【问题描述】:

这似乎应该相对(没有双关语)容易做到,但我就是想不通。我有三个表,以多对多的关系加入。一个主“问题”表、一个“状态”表(指示不同状态的名称/描述的查找表:“打开”、“进行中”、“已关闭”等)和一个中间“问题状态”表以允许主要“问题”记录的多个状态。我正在尝试编写 T-SQL 以根据 IssuesStatuses 表中的最新相关记录获取“问题”列表以及最新的 StatusName。表格如下所示:

[问题]表:
- 问题 ID (PK)
- 问题名称
- 问题描述
等等

[问题状态] 表:
- IssuesStatusesID (PK)
- 问题 ID (FK)
- 状态 ID (FK)
- 问题状态日期

[状态]表:
- 状态 ID (PK)
- 状态名称

用户在更新主要问题记录的状态时,将向 IssuesStatuses 表添加多条记录(对于相同的 IssueID)。因此,此查询应获取 [Issues] 记录、来自 [IssuesStatuses] 表的该记录的最新状态,以及来自与该 IssuesStatuses 记录关联的 [Statuses] 表的关联 StatusName 记录。我很确定我需要子查询和/或 Max(StatusDate) 函数,但是当我在 SQL 中尝试这样做时,我开始编写过于复杂的嵌套子查询。

这有意义吗?有人可以帮我解决这个问题吗?

【问题讨论】:

    标签: sql sql-server subquery relationship


    【解决方案1】:

    状态是所谓的缓慢变化的维度。处理这些问题的一种方法是为记录设置“生效”和“结束”日期。使用EffDateEndDate,您想要的查询将非常简单:

    select *
    from IssueStatus ist
    where EndDate is NULL
    

    where EndDate = '9999-01-01' -- or whatever your far out future date is
    

    缺点是插入新状态需要两个步骤:

    1. 设置当前状态的EndDate
    2. 插入新记录

    您通常会将此逻辑封装在存储过程或触发器中。

    根据您的数据结构,您可以使用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) 上有索引时,数据库引擎会很好地优化此查询。

    【讨论】:

    • 谢谢!我肯定会考虑将 EndDate 字段添加到表中;该数据库尚未投入生产。仅查看您的最后一个示例(我现在不在 SSMS 中),我猜我可以将 ist 加入查找表(状态)以获得状态的漂亮名称?跨度>
    • @TheDudeDude 。 . .是的。我应该添加到答案“我只显示使用IssueStatus 表的部分,但所有查询都可以通过加入其他表来修改。”
    猜你喜欢
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2014-09-16
    • 2018-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多