【问题标题】:Multiple outer joins that can include empty subset可以包含空子集的多个外连接
【发布时间】:2012-10-15 12:20:38
【问题描述】:

我有一个对象表和一个属性表,其中包含对象可能具有或不具有的各种属性。

我想获取对象的所有属性,如果没有属性,则为 null。

我第一次尝试查询是这样的:

SELECT o.Id ,
aa.Value AS AttributeA, 
ab.Value AS AttributeB, 
ac.Value AS AttributeC
FROM Objects o
LEFT OUTER JOIN Attributes aa
ON (o.Id = aa.ObjectId)
LEFT OUTER JOIN Attributes ab
ON (o.Id = ab.ObjectId)
LEFT OUTER JOIN Attributes ac    
ON (o.Id = ac.ObjectId)
WHERE (aa.AttributeTypeId = 1 OR aa.AttributeTypeId IS NULL)
AND (ab.AttributeTypeId = 2 OR ab.AttributeTypeId IS NULL)
AND (ac.AttributeTypeId = 3 OR ac.AttributeTypeId IS NULL)
AND o.Id = @objectId

这样做的问题是,如果还没有对象具有属性 a,那么 aa 子集是空的,因此只会返回根本没有属性的对象。

如何让 SQL Server 在不涉及大量 UNION(属性类型的数量为 20+)的情况下返回所有对象,即使是混合属性场景?

【问题讨论】:

    标签: sql sql-server pivot outer-join is-empty


    【解决方案1】:

    过滤外连接的目标时,应将过滤器放在连接上。

    即:

    FROM Objects o 
    LEFT OUTER JOIN Attributes aa 
    ON (o.Id = aa.ObjectId) and (aa.AttributeTypeId = 1)
    

    【讨论】:

      【解决方案2】:

      我想出了使用枢轴的方法。如果根本没有属性记录,它仍然会失败,但这很容易通过只有一个属性的虚拟对象来解决。

      SELECT pvt.ObjectId, 
      pvt.[1] AS [AttributeA],
      pvt.[2] AS [AttributeB],
      pvt.[3] AS [AttributeC]
      FROM
      (
          SELECT o.ObjectId, att.Value, att.AttributeTypeId 
          FROM Objects o
          LEFT OUTER JOIN Attributes att ON o.Id = att.ObjectId
          WHERE o.Id = @objectId
      ) attributes
      PIVOT( MAX(Value) FOR AttributeTypeId 
      IN ([1], [2], [3])) pvt
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-25
        • 1970-01-01
        • 2019-11-08
        • 1970-01-01
        相关资源
        最近更新 更多