我有一个名为Sub_Router的表,下面有示例数据,只有两列
Associated_Router_L1,Associated_Router_L2都是复合主键。
我想为给定的L1 Routerid选择所有L2 Ronter id 例如,如果给出了2001年的结果2005,2006,2002,2007,2003,2008
我的选择sql是
查询 - 1(有一个级别)
select s1.Associated_Router_L2
from Sub_Router s1
where s1.Associated_Router_L1 in (select s2.Associated_Router_L2
from Sub_Router s2
where s2.Associated_Router_L1 = 2001)
查询 - 2(有两级)
select s1.Associated_Router_L2
from Sub_Router s1
where s1.Associated_Router_L1 in (select s2.Associated_Router_L2
from Sub_Router s2
where s2.Associated_Router_L1 in (select s3.Associated_Router_L2
from Sub_Router s3
where s3.Associated_Router_L1 = 2001))
使用内部联接的查询-2
从Sub_Router s1选择s1.Associated_Router_L2 INNER JOIN Sub_Router s2 ON s1.Associated_Router_L1 = s2.Associated_Router_L2 INNER join s_Associated_Router_L1 = s3.Associated_Router_L2上的Sub_Router s3其中s1.Associated_Router_L1 = 2001或s2.Associated_Router_L1 = 2001或s3.Associated_Router_L1 = 2001
OR操作再次创建性能
结果很好,任何更好的方法来避免这个IN,OR运算符。
表名:Sub_Router
列名:Associated_Router_L1,Associated_Router_L2
两个复合主键
附加数据
Associated_Router_L1 Associated_Router_L2
2000 2001
2000 2002
2000 2003
2000 2004
2001 2005
2001 2006
2001 2002
2002 2007
2002 2003
2002 2008
答案 0 :(得分:0)
标准SQL不擅长处理分层/树模型。
例如,Oracle已添加CONNECT BY ...
以支持hierarchical queries作为非标准扩展
使用标准SQL,典型的方法是' Nested Set Model', 或者你可以使用OQGraph storage engine用于MySQL / MariaDB
答案 1 :(得分:0)
以下sql可能有所帮助:
SELECT DISTINCT concat(s2.Associated_Router_L1, '-->', s2.Associated_Router_L2) branch
FROM Sub_Router s1, Sub_Router s2
WHERE
s1.Associated_Router_L1 = 2001
AND (s1.Associated_Router_L2 = s2.Associated_Router_L1 OR 2001 = s2.Associated_Router_L1)
如果你想更深入一个杠杆,添加另一个表,展开WHERE子句,并修改SELECT字段:
SELECT DISTINCT concat(s3.Associated_Router_L1, '-->', s3.Associated_Router_L2) branch
FROM Sub_Router s1, Sub_Router s2, Sub_Router s3
WHERE
s1.Associated_Router_L1 = 2001
AND (s1.Associated_Router_L2 = s2.Associated_Router_L1 OR 2001 = s2.Associated_Router_L1)
AND (s2.Associated_Router_L2 = s3.Associated_Router_L1 OR s1.Associated_Router_L2 = s3.Associated_Router_L1 OR 2001 = s3.Associated_Router_L1)
答案 2 :(得分:0)
可能没有任何更快,但至少可以工作到任意深度,而无需在数据或嵌套深度发生变化时重写查询。
CREATE TEMPORARY TABLE Router_List (
Router int)
Declare @Input_Router int
Set @Input_Router = 2001
--Prime the pump
Insert into @Router_List (Router) Values(@Input_Router)
While (1=1)
Begin
Insert into @Router_List (Router)
Select Associated_router_L2
From Sub_Router SR
Inner Join @Router_List RL
On SR.Associated_Router_L1 = RL.Router
Left Join @Router_List RL2
On SR.Associated_Router_L2 = RL2.Router
Where RL2.Router is Null
--Till nothing to do
If @@ROWCOUNT = 0 Break
End
Select * from @Router_List