我有3个表之间的关系,我们称之为tree
,parent
和children
。
我想(总是)获取树,如果没有删除则获取父级,或者如果未删除,则删除未删除的子级和子级。
以下查询使用异常,它不会获取树。
SELECT *
FROM tree t
LEFT JOIN parent p ON t.id = p.tree_id
LEFT JOIN children c ON p.id = c.parent_id
WHERE t.id = 2599
AND (p.deleted = false OR (p.deleted = true AND pc.deleted = false));
有什么想法吗?
答案 0 :(得分:1)
正如评论中所提到的,看起来你在第二次加入时遇到了问题。
此外,您的WHERE
子句会将LEFT JOIN
转换为INNER JOIN
s:
- NULL
永远不会等于TRUE或FALSE
我会尝试这样的事情......
SELECT
*
FROM
tree AS t
LEFT JOIN
(
parent AS p
LEFT JOIN
children AS c
ON c.parent_id = p.id
AND c.deleted = false
)
ON (t.id = p.tree_id)
AND (c.id IS NOT NULL OR p.deleted = false)
WHERE
t.id = 2599
children
仅与parent
相关联,因为它们未被删除。
如果tree
未被删除,或者有子女(我们已经确保只有在未删除时才包含这些内容),该加入才会与parent
相关联
编辑:
我从不喜欢使用RIGHT JOIN
,但也许它可以更具可读性?我不这么认为,但我会把它包括在内以便完整。
SELECT
*
FROM
parent AS p
LEFT JOIN
children AS c
ON c.parent_id = p.id
AND c.deleted = false
RIGHT JOIN
tree AS t
ON (t.id = p.tree_id)
AND (c.id IS NOT NULL OR p.deleted = false)
WHERE
t.id = 2599
答案 1 :(得分:0)
实际上并不困难。 (编辑:我希望我从来没有说过这个;-)只确保正确处理外连接记录(即检查为空)。
SELECT *
FROM tree t
LEFT JOIN parent p ON t.id = p.tree_id
LEFT JOIN children c ON p.id = c.parent_id and c.deleted = false
WHERE t.id = 2599
AND (p.id is null OR p.deleted = false OR c.deleted = false) -- parent okay?
AND (c.id is null OR c.deleted = false) -- child okay?