棘手的递归MySQL查询
我有一个表,它有两列,usersID和它们的兄弟ID 找到给定用户的所有兄弟姐妹的最佳方法是什么 这个问题很复杂。这里有一个例子 用户1有5个兄弟2,3,4,5,6 这张桌子看起来像这样棘手的递归MySQL查询,mysql,sql,Mysql,Sql,我有一个表,它有两列,usersID和它们的兄弟ID 找到给定用户的所有兄弟姐妹的最佳方法是什么 这个问题很复杂。这里有一个例子 用户1有5个兄弟2,3,4,5,6 这张桌子看起来像这样 userID|siblingID 1 | 2 1 | 3 6 | 5 5 | 3 3 | 1 4 | 6 可以使用循环和临时表模拟递归。首先在临时表中插入开始节点。然后,当临时表中有行时,获取第一行,将其从临时表中删除,并在此处插入其所有兄弟姐妹…您可以使用循环
userID|siblingID
1 | 2
1 | 3
6 | 5
5 | 3
3 | 1
4 | 6
可以使用循环和临时表模拟递归。首先在临时表中插入开始节点。然后,当临时表中有行时,获取第一行,将其从临时表中删除,并在此处插入其所有兄弟姐妹…您可以使用循环和临时表模拟递归。首先在临时表中插入开始节点。然后,当临时表中有行时,获取第一行,将其从临时表中删除,并在其位置插入其所有兄弟姐妹…就是一个示例,其中有人必须获取某些条目的所有亲属 相应的堆栈溢出问题如下: 就是一个例子,在这个例子中,某人必须获得某些条目的所有亲属 相应的堆栈溢出问题如下: ANSI SQL:
with recursive tree (userid, siblingid) as
(
select userid,
siblingid
from users
where userId = 1
union all
select c.userid,
c.siblingid
from users c
join tree p on p.userid c.siblingId
)
select *
from tree;
对于Oracle 11.2和SQL Server(他们显然没有仔细查看ANSI规范),您需要删除递归关键字,根据标准ANSI SQL:
with recursive tree (userid, siblingid) as
(
select userid,
siblingid
from users
where userId = 1
union all
select c.userid,
c.siblingid
from users c
join tree p on p.userid c.siblingId
)
select *
from tree;
对于Oracle 11.2和SQL Server(他们显然没有仔细查看ANSI规范),您需要删除递归关键字。根据标准,它是强制性的。即使使用了多个SQL语句,答案也比我想象的要难得多 问题的简单答案是:创建一个包含所有兄弟关系的表。然后,您可以通过以下方式查询:
select siblingid
from @allsiblings sa
where sa.userid = 3
一个音符。我使用SQL Server的语法,只是因为它恰好是最方便的数据库。我只在MySQL中使用功能,所以它应该很容易翻译
如何创建@AllSides表?好吧,继续添加不存在的兄弟姐妹对,直到没有更多的兄弟姐妹对可添加。我们通过进行自连接来获得配对
以下是受前面警告约束的代码:
declare @allsiblings table (userid integer, siblingid integer);
declare @siblings table (userId int, siblingID int);
-- Initialize the @siblings table
insert into @siblings(userId, siblingID)
select 1 as userID, 2 as siblingID union all
select 1 as userID, 3 as siblingID union all
select 6 as userID, 5 as siblingID union all
select 5 as userID, 3 as siblingID union all
select 3 as userID, 1 as siblingID union all
select 4 as userID, 6 as siblingID;
-- Initialize all siblings. Note that both pairs are going in here
insert into @allsiblings(userid, siblingid)
select userId, siblingid from @siblings union
select siblingID, userid from @siblings
-- select * from @allsiblings
while (1=1)
begin
-- Add in new siblings, that don't exist by doing a self-join to traverse the links
insert into @allsiblings
select distinct sa.userid, sa2.siblingid
from @allsiblings sa join
@allsiblings sa2
on sa.siblingid = sa2.userid
where not exists (select * from @allsiblings sa3 where sa3.userid = sa.userid and sa3.siblingid = sa2.siblingid)
-- If nothing was added, we are done
if (@@ROWCOUNT = 0) break;
select * from @allsiblings;
end;
答案是,即使使用多个SQL语句,也比我想象的要困难得多 问题的简单答案是:创建一个包含所有兄弟关系的表。然后,您可以通过以下方式查询:
select siblingid
from @allsiblings sa
where sa.userid = 3
一个音符。我使用SQL Server的语法,只是因为它恰好是最方便的数据库。我只在MySQL中使用功能,所以它应该很容易翻译
如何创建@AllSides表?好吧,继续添加不存在的兄弟姐妹对,直到没有更多的兄弟姐妹对可添加。我们通过进行自连接来获得配对
以下是受前面警告约束的代码:
declare @allsiblings table (userid integer, siblingid integer);
declare @siblings table (userId int, siblingID int);
-- Initialize the @siblings table
insert into @siblings(userId, siblingID)
select 1 as userID, 2 as siblingID union all
select 1 as userID, 3 as siblingID union all
select 6 as userID, 5 as siblingID union all
select 5 as userID, 3 as siblingID union all
select 3 as userID, 1 as siblingID union all
select 4 as userID, 6 as siblingID;
-- Initialize all siblings. Note that both pairs are going in here
insert into @allsiblings(userid, siblingid)
select userId, siblingid from @siblings union
select siblingID, userid from @siblings
-- select * from @allsiblings
while (1=1)
begin
-- Add in new siblings, that don't exist by doing a self-join to traverse the links
insert into @allsiblings
select distinct sa.userid, sa2.siblingid
from @allsiblings sa join
@allsiblings sa2
on sa.siblingid = sa2.userid
where not exists (select * from @allsiblings sa3 where sa3.userid = sa.userid and sa3.siblingid = sa2.siblingid)
-- If nothing was added, we are done
if (@@ROWCOUNT = 0) break;
select * from @allsiblings;
end;
你在使用什么数据库?我假设您正在寻找递归解决方案,所以5、3和1都是6的兄弟。您使用的是什么数据库?我假设您正在寻找递归解决方案,因此5、3和1都是6的兄弟姐妹。感谢您的帮助!我忘了指定我正在使用MySQL。这似乎对我不起作用MySQL@Jakobovski:正确。MySQL不支持任何现代SQL功能,如递归查询、窗口功能等。是否需要使用MySQL执行此操作,还是需要在PHP数据库之外执行此操作?@Jakobovski:使用MySQL时,最好使用PHP执行此操作。这如何处理循环?感谢帮助!我忘了指定我正在使用MySQL。这似乎对我不起作用MySQL@Jakobovski:正确。MySQL不支持任何现代SQL功能,如递归查询、窗口功能等。MySQL是否可以这样做,或者我需要在PHP数据库之外这样做?@Jakobovski:MySQL最好使用PHP。这是如何处理循环的?