【问题标题】:SELECT'ing a master record and all its related foreign detail records, in a single query?在单个查询中选择主记录及其所有相关的外国详细记录?
【发布时间】:2009-07-20 10:46:34
【问题描述】:

我有一张可能有数千(数百万?)记录的表。它基本上是一个存储特殊日志条目的审计跟踪表。它被称为“日志”。

还有一个名为“LogsExtended”的相关表,它为 Logs 表中的每个条目存储零个或多个附加记录。

有外键关系设置,完成删除级联等

我正在对 Logs 表执行 SELECT 以选择在特定时间范围内发生的所有记录,例如“过去 30 天”。

但是,我想以某种方式同时选择 LogsExtended 表中的相关外部记录。目的是将此查询的结果填充到具有正确 DataRelation 设置的 DataSet 中。

我尝试过使用各种 JOIN 子句,但这些都倾向于导致错误的行为——日志中的条目对于 LogsExtended 表中的每条相关记录都会重复。

我真的想避免明显的后备解决方案,即首先查询 Logs 表,然后对于每个结果,运行一个额外的查询来获取 LogsExtended 记录。这让我觉得非常浪费,可能会导致运行数千个查询。

我想我正在把它变成一座小山,但我就是想不通。

谢谢。

【问题讨论】:

    标签: .net sql ado.net


    【解决方案1】:

    您需要使用左连接,否则它不会显示来自 Logs 中没有项目 int LogExtended 的记录。就这样

    DECLARE @StartDate DATETIME,
            @EndDate DATETIME
    
    SELECT  @StartDate = '01 Jun 2009',
            @EndDate = '30 Jun 2009'
    
    SELECT  *
    FROM    Logs l LEFT JOIN
            LogsExtended le ON l.LogID = le.LogID
    WHERE   l.Date BEYWEEN @StartDate AND @EndDate
    

    如果你想要 2 个结果集,你需要执行查询

    DECLARE @StartDate DATETIME,
            @EndDate DATETIME
    
    SELECT  @StartDate = '01 Jun 2009',
            @EndDate = '30 Jun 2009'
    
    SELECT  l.*
    FROM    Logs l 
    WHERE   l.Date BEYWEEN @StartDate AND @EndDate
    
    SELECT  le.*
    FROM    Logs l INNER JOIN
            LogsExtended le ON l.LogID = le.LogID
    WHERE   l.Date BEYWEEN @StartDate AND @EndDate
    

    这将返回日期之间的所有日志,然后返回同一原始日志集的所有扩展日志

    【讨论】:

    • 第二个解决方案非常接近我想要的 :~) 谢谢。我唯一的问题是...... MSSQL 数据库会意识到 WHERE 子句已重复两次吗?它会对此进行优化,使其只执行一次吗?
    • 使用我展示的参数应该有助于优化查询,并且在列上放置索引也应该有帮助。
    • 谢谢。我决定接受你的回答,因为它让我回到了正确的轨道上。
    【解决方案2】:

    在一对多关系中join的本质是将“one”表中的行与“many”表中的行相乘。您可以采用的一种选择是仅使用 Logs 表中的 LogID,以及 LogsExtended 表中的所有其余信息:

    SELECT L.ID, E.*
    FROM Logs L, LogsExtended E
    WHERE 
    L.ID = E.ID
    AND
    (Some date limitation on the Logs table)
    

    【讨论】:

    • 虽然这会导致“一个”表字段重复,但如果需要在单个 SQL 查询/语句中执行,这可能是最好的方法。
    • 那么除了返回大量重复记录之外,没有别的办法吗?只要我在这里没有遗漏任何技巧 - 那没关系。我现在想的问题是,在我的 .NET 应用程序中将这种“平面二维”数据转换为 3D 数据的最佳方法是什么。目前,我想出了一个临时解决方案,将重复的条目聚合到一个条目中,同时将“LogsExtended”信息累积到一个集合中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多