考虑这是我的表结构。...
id | name | parent_id
19 | category1 | 0
20 | category2 | 19
21 | category3 | 20
22 | category4 | 21
......
现在,我想通过单个mysql查询获取与私有相关的行。如果我给出“ id = 22”,则查询应返回ID 21、20、19。
还需要获取(可以是单独的查询)级别的数据返回。即如果我给id = 22然后查询应该只返回id 21(第一级)。 ID 21,20(秒级)...
这里是类似的link!
接受答案几乎可以解决我的问题,但是只有在parent_id < id
时才能使用升序。
可接受的答案的一部分:
select id,
name,
parent_id
from (select * from products
order by parent_id, id) products_sorted,
(select @pv := '19') initialisation
where find_in_set(parent_id, @pv)
and length(@pv := concat(@pv, ',', id))
答案 0 :(得分:1)
您可以创建一个将遍历树的存储函数:
delimiter //
create function product_ancestors(in_id int) returns text reads sql data
begin
declare current_id int default in_id;
declare ancestor_ids text default null;
while (current_id <> 0) do
set current_id = (
select parent_id
from products
where id = current_id
);
if (current_id <> 0)
then set ancestor_ids = concat_ws(',', ancestor_ids, current_id);
end if;
end while;
return ancestor_ids;
end //
delimiter ;
与
一起使用select product_ancestors(22);
这将返回一个逗号分隔的字符串'21,20,19'
。
请参见demo
答案 1 :(得分:0)
您可以通过反转查询中的内容来修改查询中的链接
select id,
name,
parent_id, @pv
from (select * from products
order by id desc) products_sorted,
(select @pv := '21') initialisation
where find_in_set(id, @pv)
and length(@pv := concat(@pv, ',', parent_id))
答案 2 :(得分:-2)
在MySQL 8+中,您可以使用递归CTE:
with recursive cte as (
select c.id, c.parent_id
from categories c
where c.id = 22
union all
select cte.id, c.parent_id
from cte join
categories c
on c.id = cte.parent_id
)
select *
from cte;
如果需要,请使用join
来输入名称。
Here是db <>小提琴。