我是一个基本的SQL表,每行之间都有一个简单的层次连接。也就是说,每行都有一个ParentID,并使用它与另一行连接。其内容如下
AccountID | AccountName | ParentID
---------------------------------------
1 Mathew 0
2 Philip 1
3 John 2
4 Susan 2
5 Anita 1
6 Aimy 1
7 Elsa 3
8 Anna 7
.............................
.................................
45 Kristoff 8
希望结构清晰
但是我对listng的要求有点奇怪。那是当我们传递一个AccountID时,它应该列出所有的父母和兄弟姐妹和兄弟姐妹的孩子。但它永远不会将该AccountID的任何子项列入任何级别。我可以用图片更详细地解释一下。对不起,图片清晰..我的是一个旧的手机摄像头..
当我们通过AccountID 4 时,它应列出所有家长及其兄弟姐妹,但不应列出4,6,7,8,9,10 。这意味着应该在结果中避免帐户及其中的任何子项(基于图片树元素)。希望解释清楚。
答案 0 :(得分:9)
如果我说得对,你需要输出整个表格,除了4和它的所有后代,然后尝试这个递归查询:
WITH CT AS
(
SELECT * FROM T WHERE AccountID=4
UNION ALL
SELECT T.* FROM T
JOIN CT ON T.ParentID = CT.AccountId
)
SELECT * FROM T WHERE AccountID
NOT IN (SELECT AccountID FROM CT)
回答评论中的问题:
因此它不会遍历顶部。它只遍历指定 帐户。例如,如果我将4作为第一个参数传递,将2传递为第二个参数 参数,结果应该是这些值2,5,11,12
您应该从ID = 2开始并前往底部排除ID = 4,因此您在ID = 4后剪切整个子树:
WITH CT AS
(
SELECT * FROM T WHERE AccountID=2
UNION ALL
SELECT T.* FROM T
JOIN CT ON T.ParentID = CT.AccountId
WHERE T.AccountId<>4
)
SELECT * FROM CT
答案 1 :(得分:3)
试试这个:
;with cte as
(select accountid,parentid, 0 as level from tbl
where parentid = 0
union all
select t.accountid,t.parentid,(level+1) from
cte c inner join tbl t on c.accountid= t.parentid
)
select * from cte
where level < (select level from cte where accountid = @accountid)
当您传入参数@accountid
时,这将返回参数前级别上所有节点的accountid
值。
如果要返回除输入本身以外的所有输入,则可以将where
子句更改为;
where level <=(select level from cte where accountid= @accountid )
and accountid <> @accountid
在您的示例中,如果@accountid
= 4,则返回值1,2,3(祖先)以及5,13,14(兄弟姐妹)。
答案 2 :(得分:1)
这会回报你的目标吗?
declare @AccountID int
set @AccountID = 4
;with parents
as (
select AccountID, AccountName, ParentID
from Account
where AccountID = (select ParentID from Account Where AccountID = @AccountID)
union all
select A.AccountID, A.AccountName, A.ParentID
from Account as A
join parents as P
on P.ParentID = A.AccountID
),
children
as (
select AccountID, AccountName, ParentID
from parents
union all
select A.AccountID, A.AccountName, A.ParentID
from Account as A
join children as C
on C.AccountID = A.ParentID
where A.AccountID <> @AccountID
)
select distinct AccountID, AccountName, ParentID
from children
order by AccountID
答案 3 :(得分:1)
对我而言,听起来你想要进入树上。所以考虑这个测试数据
DECLARE @tbl TABLE(AccountID INT,AccountName VARCHAR(100),ParentID INT)
INSERT INTO @tbl
VALUES
(1,'Mathew',0),
(2,'Philip',1),
(3,'John',2),
(4,'Susan',2),
(5,'Anita',1),
(6,'Aimy',1),
(7,'Elsa',3),
(8,'Anna',7)
我会写一个这样的查询:
DECLARE @AcountID INT=4
;WITH CTE
AS
(
SELECT
tbl.AccountID,
tbl.AccountName,
tbl.ParentID
FROM
@tbl AS tbl
WHERE
tbl.AccountID=@AcountID
UNION ALL
SELECT
tbl.AccountID,
tbl.AccountName,
tbl.ParentID
FROM
@tbl AS tbl
JOIN CTE
ON CTE.ParentID=tbl.AccountID
)
SELECT
*
FROM
CTE
WHERE
NOT CTE.AccountID=@AcountID
这将返回如下结果:
2 Philip 1
1 Mathew 0