我有一个父/子关系表,多对多
parentid int not null
childid int not null
假设我有公司a,b,c,d,e
a
..b
....c
..c
d
..e
....b
......c
我得到了这个查询以返回一个顶级父母
FUNCTION [dbo].[getRootCompagny]
(
@root int
)
RETURNS int
AS
BEGIN
DECLARE @parent int
SELECT @parent = companyparentid from companyrelation where companychildid = @root
if @parent is not null
set @root = dbo.getRootCompagny(@parent)
RETURN @root
END
如果我通过b,我将只获得
a
..b
....c
..c
因为我写的查询只能管理一个顶级父级。 你会如何修复它以获得整棵树,就像第一个树一样?
这是我的CTE
PROCEDURE [dbo].[GetCompanyRelation]
@root int
AS
BEGIN
SET NOCOUNT ON;
set @root = dbo.getRootCompagny(@root)
WITH cieCTE(CompanyChildid, CompanyParentid, depth, sortcol)
AS
(
-- root member
SELECT @root
, null
, 0
, CAST(@root AS VARBINARY(900))
UNION ALL
-- recursive member
SELECT R.CompanyChildid
, R.CompanyParentid
, C.depth+1
, CAST(sortcol + CAST(R.CompanyChildid AS BINARY(4)) AS VARBINARY(900))
FROM CompanyRelation AS R JOIN cieCTE AS C ON R.CompanyParentid = C.CompanyChildid
)
-- outer query
SELECT cieCTE.depth
, cieCTE.CompanyChildid as ChildID
, cieCTE.CompanyParentid as ParentId
, company.[name] as [Name]
FROM cieCTE inner join company on cieCTE.CompanyChildid = company.companyid
ORDER BY sortcol
END
最后,根据上面的逻辑,我得到了一个,如何得到一个,d?
答案 0 :(得分:1)
好的,那你看看吧吗?它给出了缩进和完整的树路径
DECLARE @Table TABLE(
ID VARCHAR(10),
ParentID VARCHAR(10)
)
--INSERT INTO @Table (ID,ParentID) SELECT 'a', NULL
INSERT INTO @Table (ID,ParentID) SELECT 'b', 'a'
INSERT INTO @Table (ID,ParentID) SELECT 'c', 'a'
INSERT INTO @Table (ID,ParentID) SELECT 'c', 'b'
--INSERT INTO @Table (ID,ParentID) SELECT 'd', NULL
INSERT INTO @Table (ID,ParentID) SELECT 'e', 'd'
INSERT INTO @Table (ID,ParentID) SELECT 'b', 'e'
DECLARE @Start VARCHAR(10)
SELECT @Start = 'e'
;WITH roots AS (
SELECT *
FROM @Table
WHERE ID = @Start
UNION ALL
SELECT DISTINCT
NULL,
ParentID
FROM @Table
WHERE ParentID = @Start
AND ParentID NOT IN ( SELECT ID FROM @Table)
UNION ALL
SELECT t.*
FROM @Table t INNER JOIN
roots r ON t.ID = r.ParentID
)
, layers AS(
SELECT ParentID AS ID,
CAST(NULL AS VARCHAR(10)) AS ParentID,
CAST('' AS VARCHAR(MAX)) AS DisplayDepth,
CAST(ParentID + '\' AS VARCHAR(MAX)) AS LayerPath
FROM roots
WHERE ParentID NOT IN ( SELECT ID FROM @Table)
UNION ALL
SELECT t.*,
DisplayDepth + '[-]',
LayerPath + t.ID + '\'
FROM @Table t INNER JOIN
layers l ON t.ParentID = l.ID
)
SELECT *
FROM layers
ORDER BY LayerPath
这是你的想法吗?