Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
棘手的递归MySQL查询_Mysql_Sql - Fatal编程技术网

棘手的递归MySQL查询

棘手的递归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 可以使用循环和临时表模拟递归。首先在临时表中插入开始节点。然后,当临时表中有行时,获取第一行,将其从临时表中删除,并在此处插入其所有兄弟姐妹…您可以使用循环

我有一个表,它有两列,usersID和它们的兄弟ID

找到给定用户的所有兄弟姐妹的最佳方法是什么

这个问题很复杂。这里有一个例子

用户1有5个兄弟2,3,4,5,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。这是如何处理循环的?