我有一个混乱的数据集,我需要为特定的父帐户获取所有子帐户。
表格如下
代码(PK),名称,ParentCode
没有外键
如果帐户没有父级,我可以看到,ParentCode是一个空字符串,或者它设置为与代码相同。
我一直在尝试关注http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx,但它似乎正在返回所有数据,而且我无法弄清楚如何只为一个帐户获取孩子。
WITH DirectReports (ParentCus, Code, Name, Level)
AS
(
SELECT ParentCode, Code, Name, 0 AS Level
FROM Customers
WHERE Code = ParentCode OR Code = ''
UNION ALL
SELECT c.ParentCode, c.Code, c.Name, level + 1
FROM Customers AS C
INNER JOIN DirectReports AS d
ON c.ParentCode = d.Code
where c.Code != d.Code
)
SELECT ParentCus, Code, Name, Level
FROM DirectReports
修改 的 为了清楚起见,我需要能够通过我的函数代码并返回所有(递归)帐户子帐户。
最终代码 我不得不对答案稍作修改,但这是最终的工作代码
declare @t table(code varchar(10), name varchar(10), parentcode varchar(10))
insert @t values(1, 'navn1', '1')
insert @t values(2, 'navn2', '')
insert @t values(3, 'navn3', 1)
insert @t values(4, 'navn4', 3)
insert @t values(5, 'navn5',4)
insert @t values(6, 'navn6', 2)
insert @t values(7, 'navn7', 3)
declare @code varchar(10) -- or however code/parentcode is declared
set @code = '1' -- the parentcode you are trying to isolate
;WITH DirectReports (ParentCus, Code, Name, Level)
AS
(
SELECT ParentCode, Code, Name, 0 AS Level
FROM @t Customers
-- this picks the chosen code
WHERE Code = @code and (Code = ParentCode OR PARENTCode = '')
UNION ALL
SELECT c.ParentCode, c.Code, c.Name, level + 1
FROM
(select * from @t where code != parentcode) --had to do this to account for an infinate loop
as C
INNER JOIN DirectReports AS d
ON c.ParentCode = d.Code
)
SELECT ParentCus, Code, Name, Level
FROM DirectReports
-- level > 0: to ensure child accounts only
where level > 0
答案 0 :(得分:0)
;With CTE as
(
select ParentCode, Code, Name,row_number() over (order by (select 0)) as rn from Customers
)
,DirectReports as (ParentCus, Code, Name, Level)
AS
(
SELECT rn,ParentCode, Code, Name, 0 AS Level
FROM CTE WHERE rn=1 and (Code = ParentCode OR Code = '')
UNION ALL
SELECT c.ParentCode, c.Code, c.Name, level + 1
FROM CTE AS C
INNER JOIN DirectReports AS d
ON c.ParentCode = d.Code and c.rn=d.rn+1
where c.Code != d.Code
)
SELECT ParentCus, Code, Name, Level
FROM DirectReports
答案 1 :(得分:0)
您需要指定所需的代码。 此示例使用@t替换表Customers
declare @t table(code varchar(10), name varchar(10), parentcode varchar(10))
insert @t values(1, 'navn1', '')
insert @t values(2, 'navn2', '')
insert @t values(3, 'navn3', 1)
declare @code varchar(10) -- or however code/parentcode is declared
set @code = '1' -- the parentcode you are trying to isolate
;WITH DirectReports (ParentCus, Code, Name, Level)
AS
(
SELECT ParentCode, Code, Name, 0 AS Level
FROM @t Customers
-- this picks the chosen code
WHERE Code = @code and (Code = ParentCode OR PARENTCode = '')
UNION ALL
SELECT c.ParentCode, c.Code, c.Name, level + 1
FROM @t C
INNER JOIN DirectReports AS d
ON c.ParentCode = d.Code
-- added to prevent infinite loop,
-- I should point out that when this happens, you have bad data in your base
WHERE c.ParentCode <> c.Code
)
SELECT ParentCus, Code, Name, Level
FROM DirectReports
-- level > 0: to ensure child accounts only
-- level < 100:to prevent infinite loops caused by circular references
where level > 0 and level < 100