简体   繁体   English

MySql:按父组然后子组

[英]MySql: Group by parent then child

I have a parent-child table-structure like: 我有一个父子表结构,如:

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;

I want to query for "attr=1". 我想查询“ attr = 1”。 The result should be: 结果应为:

  • If a parent is found, output the parent and no child 如果找到父母,则输出父母而不是孩子

  • If a child is found and the parent is not found, show the found childs 如果找到了孩子但没有找到父母,请显示找到的孩子

So with the test-data above the result should be the ids 1, 5, 6, 7. 因此,对于上面的测试数据,结果应为ID 1、5、6、7。

I tried it with somehting like: 我用类似的方式尝试过:

SELECT id, parent FROM t WHERE attr=1 GROUP BY COALESCE(parent, id);

But this only finds ids 1, 5, 7 and not id 6. 但这只会找到ID 1、5、7,而不是ID 6。

Here 4 will not be taken as the attr = 0 这里4将不视为attr = 0

This is only a simplified test-structure, so it would be great if it's possible to avoid joins or sub-selects if possible to keep the query fast. 这只是一个简化的测试结构,因此,如果可以的话,可以避免连接或子选择,以保持查询的快速,那将是很好的选择。

You might be looking for something like this, using self-join 您可能正在使用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)

I have tried with the following and could get the result as expected. 我尝试了以下方法,并且可以得到预期的结果。 You might consider taking a look at it as well. 您也可以考虑看看它。

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);

I created your table and tested this, and it returns the rows you describe: 我创建了表并进行了测试,它返回了您描述的行:

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)
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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM