我有以下表格:
富
FooId INT PRIMARY KEY
FooRelationship
FooRelationshipId INT PRIMARY KEY IDENTITY
FooParentId INT FK
FooChildId INT FK
我如何编写一个返回Foo中每个id的查询以及记录的状态(无论是父级,子级还是两者都没有)。
规则:
我最初写了这个查询:
SELECT
FooId,
CASE
WHEN Parent.FooRelationshipId IS NOT NULL THEN 'Parent'
WHEN Child.FooRelationshipId IS NOT NULL THEN 'Child'
ELSE 'Neither'
END
FROM Foo F
LEFT JOIN FooRelationship Parent ON F.FooId = Parent.FooParentId
LEFT JOIN FooRelationship Child ON F.Fooid = Child.FooParentId
这是破坏的,因为如果Foo是另外两个Foos的父亲,那么它会返回该id两次。
如何将其重写为不使用连接或使用EXISTS或其他内容。
答案 0 :(得分:2)
只需使用DISTINCT
- 这是一个很好的用例。您无法使用EXISTS
,因为您实际需要从两个表中提取数据:
SELECT DISTINCT
FooId,
CASE
WHEN Parent.FooRelationshipId IS NOT NULL THEN 'Parent'
WHEN Child.FooRelationshipId IS NOT NULL THEN 'Child'
ELSE 'Neither'
END
FROM Foo F
LEFT JOIN FooRelationship Parent ON F.FooId = Parent.FooParentId
LEFT JOIN FooRelationship Child ON F.Fooid = Child.FooParentId
我通常不是DISTINCT
的忠实粉丝,因为它经常被用来隐藏凌乱的数据,但我认为这是适当的用途。
请注意,如果您在大量字段和行中使用它,可能会大大减慢速度。
如果您只想获取这些值,然后填充其余行,则可以为关系逻辑执行子查询:
SELECT s.FooID, s.Relationship, T.*
FROM Table T
INNER JOIN (SELECT DISTINCT
FooId,
CASE
WHEN Parent.FooRelationshipId IS NOT NULL THEN 'Parent'
WHEN Child.FooRelationshipId IS NOT NULL THEN 'Child'
ELSE 'Neither'
END as [Relationship]
FROM Foo F
LEFT JOIN FooRelationship Parent ON F.FooId = Parent.FooParentId
LEFT JOIN FooRelationship Child ON F.Fooid = Child.FooParentId) s
ON s.FooId = t.FooID
答案 1 :(得分:0)
尝试使用SELECT DISTINCT FooID, ...
如果您提到有问题
,它将只返回一个FooID
答案 2 :(得分:0)
只需修改现有查询即可select distinct
而非普通select
。