如何实现含多自引用列的表自连接并替换对应标题?
解决自引用双列关联返回0行的问题
我明白你碰到的问题了——当同时关联两个自引用列cgroup_1和cgroup_2时,查询返回0行,这是因为你的数据里cgroup_2列存在<null>值,而你用的是隐式内连接(通过逗号分隔表+WHERE条件),内连接会过滤掉任何一侧为null的匹配项,自然就没有符合条件的结果了。
问题原因拆解
看你的测试数据,所有行的cgroup_2都是<null>,而内连接要求c.cgroup_2 = c2.id必须严格匹配,但null和任何值都不相等,所以整个查询找不到满足两个条件的行,最终返回0条结果。
解决方案:改用左连接(LEFT JOIN)
我们需要用左连接来保留主表cgroups c的所有行,即使cgroup_2为null时,也能显示对应的c2.title为null,而不是直接过滤掉整行。对于cgroup_1,因为所有行都有有效值,用内连接或左连接都可以,但为了代码风格统一,建议都用左连接。
修改后的SQL语句如下:
select c.id, c.title, c.description, c.cunixperm, c1.title as cgroup_1_title, c2.title as cgroup_2_title from cgroups c left join cgroups c1 on c.cgroup_1 = c1.id left join cgroups c2 on c.cgroup_2 = c2.id;
为什么这个方案能生效?
LEFT JOIN会返回左表(这里是cgroups c)的所有行,无论右表是否有匹配的记录。如果右表没有匹配,对应的列会显示为null。- 对于
cgroup_1,因为你的数据里所有行的cgroup_1都是1,所以c1.title会正确显示为admin。 - 对于
cgroup_2,因为所有行都是null,c2.title会显示为null,但不会过滤掉整行数据。
额外建议:优先使用显式连接语法
你之前用的隐式内连接(逗号分隔表+WHERE条件)写法,在处理多表关联时容易出错,尤其是涉及到null值的场景。推荐使用显式的JOIN语法(LEFT JOIN/INNER JOIN等),代码可读性更高,逻辑也更清晰。
测试结果验证
用你的测试数据执行上面的SQL,会得到如下符合预期的结果:
+----+--------------+-------------+-----------+----------------+----------------+ | id | title | description | cunixperm | cgroup_1_title | cgroup_2_title | +----+--------------+-------------+-----------+----------------+----------------+ | 1 | admin | <null> | 32 | admin | <null> | | 2 | tag_mng | <null> | 32 | admin | <null> | | 3 | tags | <null> | 32 | admin | <null> | | 4 | exam_mng | <null> | 32 | admin | <null> | | 5 | exam_writer | <null> | 32 | admin | <null> | | 6 | exam_viewer | <null> | 32 | admin | <null> | | 7 | exam_starter | <null> | 32 | admin | <null> | +----+--------------+-------------+-----------+----------------+----------------+
内容的提问来源于stack exchange,提问作者LightSith
相关产品推荐
相关产品推荐

