有很多关于在MySQL递归SELECT查询的问题,但大多数的回答是,“有在Mysql的递归SELECT查询无解”。
其实是有一定的解决方案和我想清楚的知道,所以这个问题是对前一个问题是可以被发现的以下( 如何做-DO的递归选查询功能于MySQL的 )
假设你有这个表:
col1 - col2 - col3
1 - a - 5
5 - d - 3
3 - k - 7
6 - o - 2
2 - 0 - 8
&你要查找所有在COL1连接到值“1”的链接,即要打印出来:
1 - a - 5
5 - d - 3
3 - k - 7
然后你可以使用这个简单的查询:
select col1, col2, @pv:=col3 as 'col3' from table1
join
(select @pv:=1)tmp
where col1=@pv
好的,好的,但是,如果你的表中有2条记录COL1包含“1”和2条记录中含有COL1“3”,例如:
col1 - col2 - col3
1 - a - 5
1 - m - 9
5 - d - 3
3 - k - 7
6 - o - 2
3 - v - 10
2 - 0 - 8
然后,当用户搜索“1” COL1,它应该显示所有环节连接2“1”,即它应该显示这个期望的结果:
col1 - col2 - col3
1 - a - 5
1 - m - 9
5 - d - 3
3 - k - 7
3 - v - 10
所以,我的问题是我们如何修改上面的查询,以便它会显示所有环节如上述预期的结果?
编辑:@戈登,但如果我们忽略select distinct col1, col2 from
那么这个查询意味着什么,你可以在这方面的工作(因为childID的得到了提高,所以我们可以订购表1):
select col1, col2,
@pv:=(case when find_in_set(col3, @pv) then @pv else concat(@pv, ',', col3)
end) as 'col3'
from (select * from table1 order by col1) tb1 join
(select @pv:='1') tmp
on find_in_set(col1, @pv) > 0
在这种情况下,我们不担心顺序,例如,如果是这样的数据:
col1 - col2 - col3
4 - a - 5
1 - d - 2
1 - k - 4
2 - o - 3
6 - k - 8
8 - o - 9
输出将是:
col1 - col2 - col3
1 - d - 1,2
1 - k - 1,2,4
2 - o - 1,2,4,3
因此,我们得到这样的结果1,2,4,3
吧? &我们只是选择的所有记录,如果COL1是1,2,4,3
。 然后我们就可以得到最终的预期结果。
如果是这样的话,你可以认为,排除了我刚才提到的解决方案的任何特殊情况?
Answer 1:
我一直在想,如果像这样的工作:
select distinct col1, col2
from (select col1, col2,
@pv:=(case when find_in_set(col3, @pv) then @pv else concat(@pv, ',', col3)
end) as 'col3'
from table1 join
(select @pv:='1') tmp
on find_in_set(col1, @pv) > 0
) t
像这样的东西应该适用于小数据集。 然而,把所有的ID字符串中的想法是限制在一个字符串的能力。
Answer 2:
有更多的发挥。 不能让它使用用户变量,由于项目的排序工作。
但是,如果你有水平的一个合理的最大数,那么你可以做这样的事情: -
SELECT CONCAT_WS('-', a.allCols, b.allCols, c.allCols, d.allCols, e.allCols, f.allCols, g.allCols, h.allCols, i.allCols, j.allCols, k.allCols, l.allCols, m.allCols)
FROM (SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) a
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) b ON a.col3 = b.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) c ON b.col3 = c.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) d ON c.col3 = d.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) e ON d.col3 = e.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) f ON e.col3 = f.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) g ON f.col3 = g.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) h ON g.col3 = h.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) i ON h.col3 = i.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) j ON i.col3 = j.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) k ON j.col3 = k.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) l ON k.col3 = l.col1
LEFT OUTER JOIN(SELECT col1, col3, CONCAT(col1, col2, col3) AS allCols FROM table1) m ON l.col3 = m.col1
WHERE a.col1 = 1
这是多达13个级别(正常,只在您的测试数据用一对夫妇)的应对,并会给出一个逗号分隔位的每一列,每一行用破折号连接( - )。
Answer 3:
在我有限的层次,水平的深,我用了以下内容:
父母:
select * from mytable
join (
select A.id Aid,B.id Bid, C.id Cid, D.id Did, E.id Eid, F.id Fid,G.id Gid, H.id Hid from mytable A
left join mytable B on B.id=A.parent
left join mytable C on C.id=B.parent
left join mytable D on D.id=C.parent
left join mytable E on E.id=D.parent
left join mytable F on F.id=E.parent
left join mytable G on G.id=F.parent
left join mytable H on H.id=G.parent
where A.id=9
) X
where id in (Aid,Bid,Cid,Did,Eid,Fid,Gid,Hid);
儿童:
select * from mytable where id in (
select distinct id from mytable
join (
select A.id Aid,B.id Bid, C.id Cid, D.id Did, E.id Eid, F.id Fid,G.id Gid, H.id Hid FROM mytable A
left join mytable B on B.parent=A.id
left join mytable C on C.parent=B.id
left join mytable D on D.parent=C.id
left join mytable E on E.parent=D.id
left join mytable F on F.parent=E.id
left join mytable G on G.parent=F.id
left join mytable H on H.parent=G.id
Where A.id=1
) X
where id in (Aid,Bid,Cid,Did,Eid,Fid,Gid,Hid)
);
Answer 4:
存储过程做到这一点的最好办法。 因为如果数据遵循同样的顺序戈登的解决方案只会工作。
如果我们有这样的表结构
col1 - col2 - col3
3 - k - 7
5 - d - 3
1 - a - 5
6 - o - 2
2 - 0 - 8
它不会工作。
下面是一个示例程序代码来实现相同的。
delimiter //
CREATE PROCEDURE chainReaction
(
in inputNo int
)
BEGIN
declare final_id int default NULL;
SELECT col3 into final_id from table1
where col1 = inputNo;
if( final_id is not null) then
insert into results(select col1, col2, col3 from table1 where col1 = inputNo);
CALL chainReaction(final_id);
end if;
END//
delimiter ;
call chainReaction(1);
select * from results;
drop table if exists results;
文章来源: @ Symbol - a solution for Recursive SELECT query in Mysql?