我有一个父子表结构,如:
CREATE TABLE t (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`),
`parent` int(10) unsigned DEFAULT NULL, INDEX parent(`parent`),
`attr` tinyint(1) NOT NULL DEFAULT '0'
);
INSERT INTO t SET id=1, parent=null, attr=1;
INSERT INTO t SET id=2, parent=1, attr=1;
INSERT INTO t SET id=3, parent=1, attr=1;
INSERT INTO t SET id=4, parent=null, attr=0;
INSERT INTO t SET id=5, parent=4, attr=1;
INSERT INTO t SET id=6, parent=4, attr=1;
INSERT INTO t SET id=7, parent=null, attr=1;
INSERT INTO t SET id=8, parent=null, attr=0;
我想查询“attr = 1”。结果应该是:
如果找到父级,则输出父级而不输出子级
如果找到孩子且未找到父母,请显示找到的孩子
因此,使用上面的测试数据,结果应该是ids 1,5,6,7。
我尝试过这样的事情:
SELECT id, parent FROM t WHERE attr=1 GROUP BY COALESCE(parent, id);
但这只能找到ID 1,5,7而不是id 6。
这里4不会被视为attr = 0
这只是一个简化的测试结构,所以如果可能的话,可以避免连接或子选择,以保持查询的快速性。
答案 0 :(得分:2)
您可能正在使用self-join
SELECT COALESCE(parent.id, child.id)
FROM t child
left join t parent on (parent.id = child.parent and parent.attr = 1 )
WHERE child.attr = 1
GROUP BY COALESCE(parent.id, child.id)
答案 1 :(得分:1)
我尝试了以下内容,可以按预期获得结果。你也可以考虑看看它。
select id, parent from t
where attr = 1
and (parent not in
(select id from t where parent is NULL and attr = 1)
or parent is NULL);
答案 2 :(得分:0)
我创建了你的表并测试了它,它返回你描述的行:
SELECT
t1.id,
t1.parent
FROM t as t1
LEFT JOIN t as t2
ON t1.parent = t2.id
WHERE (COALESCE(t1.attr,0) = 1 OR COALESCE(t2.attr,0) = 1)
AND COALESCE(t2.attr,0) <> COALESCE(t1.attr,0)
答案 3 :(得分:0)
select distinct
case when t.parent is not null and p.attr = 1 then t.parent
else t.id
end id
from t left join t p
on t.parent = p.id
where t.attr = 1