选择自引用表上任何其他行未指向的行

时间:2017-08-19 01:27:32

标签: php mysql sql codeigniter

我有一个自我引用表,但是我无法找到没有任何其他行指向它的行 - 或者,换句话说,得到那些不是任何其他人的父母,这意味着,他们当然没有孩子。

这是我的样本数据表:

+----+------+--------+
| id | name | cat_id |
+----+------+--------+
|  1 | C1   |        |
|  2 | C2   |        |
|  3 | C3   |      1 |
|  4 | C4   |      2 |
|  5 | C5   |      2 |
|  6 | C6   |      5 |
+----+------+--------+

此处,cat_id是父母。这是一个'代表':

. ├── C1 | └── C3 └── C2 ├── C4 └── C5 └── C6

如图所示,类别可以无限期地具有子类别,并通过指向cat_id来定义。如果它是主要的'类别,它只是没有指向任何东西。我可以获得拥有父母的所有类别'选择NULL中的cat_id,但如何选择没有孩子的类别?

我试过了:

SELECT
    c1.id, c1.name, c1.cat_id
FROM
    cat c1
INNER JOIN
    cat c2
ON
    c1.id != c2.cat_id

但这不仅会返回重复的行,还会包含具有子级的类别。 预期结果在表示中以粗体显示。您可以在this SQLFiddle中运行测试。

我怎样才能做到这一点?没有递归就可以实现吗?

3 个答案:

答案 0 :(得分:2)

查找没有子节点的节点的一种方法是使用not exists仅选择cat_id列中未被引用为父节点的行:

select id from cat c1
where not exists (
    select 1 from cat c2 where c2.cat_id = c1.id
)

答案 1 :(得分:2)

这可能是您在初始查询中的目标:

select a.*
from cat a left outer join
   cat b on a.id = b.cat_id
where b.cat_id is null

答案 2 :(得分:1)

试试这个:

select * from cat
where id not in (
    select distinct cat_id 
    from cat
    where cat_id is not null)

查找没有任何其他行指向它的行,意味着找到'id'列不在'cat_id'列的任何行的行。