【问题标题】:How to correctly join table which may return more than one row如何正确连接可能返回多行的表
【发布时间】:2014-12-04 11:02:33
【问题描述】:

我有一个表 Items,其中包含以下列:

项目ID ||管理员用户ID ||物品名称

我尝试使用 ItemAttributes 加入它:

ItemAttributeId ||项目编号 ||属性值

其中一个 ItemId 可以有多个 ItemAttributeId 值分配给它。

我创建了从两个表中检索项目值的过程:

 SELECT 
    i.ItemID,
    i.AdminUserID,
    i.ItemName,
    attr1.AttributeValue as IsForEmailRobotProcessingValue,
    attr2.AttributeValue as RobotScheduledHoursValue -- HERE IS THE PROBLEM
FROM [dbo].[Items] i WITH (NOLOCK)
    LEFT JOIN [dbo].ItemAttributes attr1 WITH(NOLOCK)
        ON attr1.ItemID = i.ItemID and attr1.ItemAttributeID = 1
    LEFT JOIN [dbo].ItemAttributes attr2 WITH(NOLOCK)
    ON attr2.ItemID = i.ItemID and attr2.ItemAttributeID = 2
WHERE ((attr1.AttributeValue IS NOT NULL AND attr1.AttributeValue = 'true') OR 
    @OnlyForEmailRobotProcessing = 0)
ORDER BY ItemName

我不喜欢这里的是我 LEFT JOIN 两次同一个表,并根据相同的 ItemId 为每个连接创建了不同的别名。有没有更好的方法来 LEFT JOIN 一次并为每个 ItemAttributeId 创建两个不同的别名?谢谢!

【问题讨论】:

    标签: sql sql-server stored-procedures join


    【解决方案1】:

    试试这个:

    SELECT 
        i.ItemID,
        i.AdminUserID,
        i.ItemName,
        attr1.AttributeValue1 as IsForEmailRobotProcessingValue,
        attr1.AttributeValue2 as RobotScheduledHoursValue 
    FROM [dbo].[Items] i WITH (NOLOCK)
        LEFT JOIN
                (select ItemId,  (select AttributeValue 
                                  from  [dbo].ItemAttributes a
                                  where a.ItemId = b.ItemId and a.ItemAttributeID = 1) as AttributeValue1,
                                  (select AttributeValue 
                                  from  [dbo].ItemAttributes c
                                  where c.ItemId = b.ItemId and c.ItemAttributeID = 2) as AttributeValue2
                 from    [dbo].ItemAttributes b  WITH(NOLOCK)
                 where b.ItemId = i.ItemID  and b.ItemAttributeID in (1,2)
    
                    ) attr1 on i.ItemId  = attr1.ItemId
    
    WHERE ((attr1.AttributeValue IS NOT NULL AND attr1.AttributeValue = 'true') OR 
        @OnlyForEmailRobotProcessing = 0)
    ORDER BY ItemName
    

    【讨论】:

    • 感谢您的回答。你认为这比我的版本更有效吗?
    • 你必须检查你的执行计划才能衡量性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2011-03-20
    • 2023-04-11
    • 2021-02-24
    • 2016-05-12
    • 2013-01-23
    相关资源
    最近更新 更多