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

Sql 可以包含空子集的多个外部联接,sql,sql-server,pivot,outer-join,is-empty,Sql,Sql Server,Pivot,Outer Join,Is Empty,我有一个对象表和一个属性表,其中包含一个对象可能具有或不具有的各种属性 我希望获得对象的所有属性,如果没有属性,则为null 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 O

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

我希望获得对象的所有属性,如果没有属性,则为null

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
我的第一次查询尝试是:

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返回所有对象,即使是混合了属性场景,也不会进入大量的联合(属性类型的数量为20+)?

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

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

筛选外部联接的目标时,应将筛选器放在联接上

即: