多个外部联接,可以包含空子集

时间:2012-10-15 12:20:38

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

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

我希望获得对象的所有属性,如果没有属性,则返回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子集为空,因此只返回没有属性的对象。

如果使用混合属性场景而不进入大量UNION(属性类型的数量是20 +),我如何让SQL Server返回所有对象?

2 个答案:

答案 0 :(得分:2)

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

即:

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

答案 1 :(得分:1)

我想出了一个支点。如果根本没有属性记录,它仍然会失败,但通过只有一个属性的虚拟对象可以很容易地解决这个问题。

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