我有一个包含2列usersID
及其siblingID
查找给定用户的所有兄弟姐妹的最佳方法是什么?
问题很复杂。这是一个例子。
用户1有5个兄弟姐妹(2,3,4,5,6)
表格如下所示
userID|siblingID
1 | 2
1 | 3
6 | 5
5 | 3
3 | 1
4 | 6
答案 0 :(得分:3)
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规范 - 您需要删除recursive
关键字(根据标准是强制性的)
答案 1 :(得分:1)
即使使用多个SQL语句,答案也比我想象的要难得多。
您问题的简单答案是:创建一个包含所有兄弟关系的表格。然后您可以将其查询为:
select siblingid
from @allsiblings sa
where sa.userid = 3
一个注意事项。我正在使用SQL Server的语法,因为它恰好是最方便的数据库。我只在MySQL中使用功能,所以它应该很容易翻译。
如何创建表@AllSiblings?好吧,继续添加不存在的兄弟对,直到没有更多要添加。我们通过自我加入获得对。
以下是代码(受先前警告的影响):
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;
答案 2 :(得分:0)
您可以使用循环和临时表来模拟递归。首先在临时表中插入起始节点。然后在临时表中有行,获取第一个,从临时表中删除它,并在其中插入所有兄弟姐妹...
答案 3 :(得分:0)
http://sqlfiddle.com/#!4/0ef0c/5是一个例子,有人必须获得某些条目的所有亲属。
相应的堆栈溢出问题在这里: Hierarchical Query Needs to Pull Children, Parents and Siblings