我正在处理一个层次结构问题,其中节点有两个父节点,并且只需要获取两个父节点都在结果中的节点。
在快乐的世界里,这个查询将是完美的
WITH RECURSIVE granters (id, parents) AS (
SELECT id FROM `hierarchy` WHERE id in ("id1", "id2", "id6"....)
UNION ALL
SELECT h1.id, h1.parents FROM `hierarchy` h1
WHERE h1.parent2 in (SELECT id FROM granters)
AND h1.parent2 in (SELECT id FROM granters)
)
SELECT * FROM granters g
但是mysql不允许在多个内连接或右连接中使用CTE作为子查询,所以,我不知道如何过滤它。
我最好的方法是这样的:
WITH RECURSIVE granters (id) AS (
SELECT id FROM `hierarchy` WHERE id in ("A", "B")
UNION ALL
SELECT h1.id FROM `hierarchy` h1 INNER JOIN granters g
ON h1.parent1 = g.id
OR h1.parent2 = g.id
)
SELECT * FROM hierarchy g
WHERE g.id IN ("A", "B")
OR (
g.parent1 IN (SELECT * FROM granters)
AND g.parent2 IN (SELECT * FROM granters)
)
但问题是,首先返回至少有一个父级的所有元素,然后过滤后所有元素都没有所有父级......但如果缺少祖父,无论如何都会返回该节点,因为父级都在授予者中。
数据
id | 家长1 | 家长2 |
---|---|---|
A | A1 | A2 |
B | B1 | B2 |
C | A | B |
D | B | H |
E | C | D |
实际产量:
身份证 | 家长1 | 家长2 | 笔记 |
---|---|---|---|
A | A1 | A2 | 好,是选定值 |
B | B1 | B2 | 不错,就是选值了 |
C | A | B | 很好,A 和 B 都在结果中 |
E | C | D | 糟糕,D 缺失,因为 H 缺失 |
预期输出:
身份证 | 家长1 | 家长2 |
---|---|---|
A | A1 | A2 |
B | B1 | B2 |
C | A | B |
-- Data
CREATE TABLE `hierarchy` (
`id` char(36) NOT NULL,
`parent1` char(36),
`parent2` char(36),
PRIMARY KEY (`id`)
);
INSERT INTO `hierarchy` (id,parent1,parent2) VALUES
('A','A1','A2'),
('B','B1','B2'),
('C','A','B'),
('D','B','H'),
('E','C','D');
您需要加入 CTE 两次。您的查询正在测试
parent1
和 parent2
是否等于相同的父 ID。
WITH RECURSIVE granters (id) AS (
SELECT id FROM `hierarchy` WHERE id in ("A", "B")
UNION ALL
SELECT h1.id FROM `hierarchy` h1
INNER JOIN granters g1 ON h1.parent1 = g1.id
INNER JOIN granters g2 ON h1.parent2 = g2.id
)