MySql:按父母分组然后分组

时间:2018-04-02 09:05:19

标签: mysql sql

我有一个父子表结构,如:

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

这只是一个简化的测试结构,所以如果可能的话,可以避免连接或子选择,以保持查询的快速性。

4 个答案:

答案 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