gpt4 book ai didi

sql - MySQL 递归查询

转载 作者:行者123 更新时间:2023-11-30 01:17:53 25 4
gpt4 key购买 nike

我的数据库架构如下所示:

Table t1:
id
valA
valB

Table t2:
id
valA
valB

我想要做的是,对于其中一个表中的给定行集,查找两个表中具有相同 valA 或 valB 的行(将 valA 与 valA 和 valB 进行比较valB,而不是 valA 和 valB)。 然后,我想查找与上一个查询结果中的行具有相同 valA 或 valB 的行,依此类推

Example data:

t1 (id, valA, valB):
1, a, B
2, b, J
3, d, E
4, d, B
5, c, G
6, h, J

t2 (id, valA, valB):
1, b, E
2, d, H
3, g, B


Example 1:

Input: Row 1 in t1
Output:
t1/4, t2/3
t1/3, t2/2
t2/1
...


Example 2:

Input: Row 6 in t1
Output:
t1/2
t2/1

我想要在结果中找到该行的搜索级别(例如,在示例 1 中:t1/2 和 t2 的级别 1)/1,t1/5 的级别 2,...)有限深度的递归没问题。随着时间的推移,我可能想在查询中包含更多遵循相同模式的表。如果可以轻松地为此目的扩展查询,那就太好了。

但最重要的是性能。你能告诉我最快的方法来完成这个任务吗?

提前致谢!

最佳答案

尝试一下,虽然它还没有完全测试,但看起来它正在工作:P(http://pastie.org/1140339)

drop table if exists t1;
create table t1
(
id int unsigned not null auto_increment primary key,
valA char(1) not null,
valB char(1) not null
)
engine=innodb;

drop table if exists t2;
create table t2
(
id int unsigned not null auto_increment primary key,
valA char(1) not null,
valB char(1) not null
)
engine=innodb;

drop view if exists t12;
create view t12 as
select 1 as tid, id, valA, valB from t1
union
select 2 as tid, id, valA, valB from t2;

insert into t1 (valA, valB) values
('a','B'),
('b','J'),
('d','E'),
('d','B'),
('c','G'),
('h','J');

insert into t2 (valA, valB) values
('b','E'),
('d','H'),
('g','B');

drop procedure if exists find_children;

delimiter #

create procedure find_children
(
in p_tid tinyint unsigned,
in p_id int unsigned
)
proc_main:begin

declare done tinyint unsigned default 0;
declare dpth smallint unsigned default 0;


create temporary table children(
tid tinyint unsigned not null,
id int unsigned not null,
valA char(1) not null,
valB char(1) not null,
depth smallint unsigned default 0,
primary key (tid, id, valA, valB)
)engine = memory;

insert into children select p_tid, t.id, t.valA, t.valB, dpth from t12 t where t.tid = p_tid and t.id = p_id;

create temporary table tmp engine=memory select * from children;

/* http://dec.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */

while done <> 1 do

if exists(
select 1 from t12 t
inner join tmp on tmp.valA = t.valA or tmp.valB = t.valB and tmp.depth = dpth) then

insert ignore into children
select
t.tid, t.id, t.valA, t.valB, dpth+1
from t12 t
inner join tmp on tmp.valA = t.valA or tmp.valB = t.valB and tmp.depth = dpth;

set dpth = dpth + 1;

truncate table tmp;
insert into tmp select * from children where depth = dpth;

else
set done = 1;
end if;

end while;

select * from children order by depth;

drop temporary table if exists children;
drop temporary table if exists tmp;

end proc_main #


delimiter ;


call find_children(1,1);

call find_children(1,6);

关于sql - MySQL 递归查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18871873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com