2

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

我想获取对象的所有属性,如果没有属性,则为 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+)?

4

2 回答 2

2

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

IE:

FROM Objects o 
LEFT OUTER JOIN Attributes aa 
ON (o.Id = aa.ObjectId) and (aa.AttributeTypeId = 1)
于 2012-10-15T12:22:59.180 回答
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
于 2012-10-15T12:20:38.247 回答