Sql server 创建链接ID

Sql server 创建链接ID,sql-server,Sql Server,我有下表: Account_Number Parent_Account Child_Account R003247 R000355 R000002 R000355 NULL R003247 R000002 R003247 NULL R004853 NULL R028636 R004853 NULL R028638 R

我有下表:

Account_Number  Parent_Account  Child_Account
R003247         R000355         R000002
R000355         NULL            R003247
R000002         R003247         NULL
R004853         NULL            R028636
R004853         NULL            R028638
R004853         NULL            R028637
R028636         R004853         NULL
R028638         R004853         NULL
R028637         R004853         NULL
其中可以加载:

create table dbo.temptable
(Account_Number varchar(10),
Parent_Account varchar(10),
Child_Account varchar(10))

insert into dbo.temptable
values
('R003247','R000355','R000002'),
('R000355',NULL,'R003247'),
('R000002','R003247',NULL),
('R004853',NULL,'R028636'),
('R004853',NULL,'R028638'),
('R004853',NULL,'R028637'),
('R028636','R004853',NULL),
('R028638','R004853',NULL),
('R028637','R004853',NULL)
此表表示帐号的拆分和重新分配。它与跟踪地块的分割和组合有关

如上表所示,前三行应分组在一起,因为它来自
R000355
-->
R003247
-->
R000002

如上表所示,最后6个也应分组,如图所示,
R004853
分为三个
R028636
R028637
R028638

我尝试过许多类似的变化:

SELECT CE.*,TT.ID
FROM dbo.temptable CE 
INNER JOIN
    (
    SELECT ACCOUNT_NUMBER,ROW_NUMBER() OVER (ORDER BY ACCOUNT_NUMBER) AS ID
    FROM(
    SELECT DISTINCT ACCOUNT_NUMBER FROM dbo.temptable where Child_Account is not null)AA
    )TT 
ON TT.ACCOUNT_NUMBER = CE.Account_Number OR TT.Account_Number = CE.Child_Account
其中包括:

Account_Number  Parent_Account  Child_Account   ID
R000355         NULL            R003247         1
R003247         R000355         R000002         2
R000355         NULL            R003247         2
R004853         NULL            R028636         3
R004853         NULL            R028638         3
R004853         NULL            R028637         3
我真正需要的是:

Account_Number  Parent_Account  Child_Account   ID
R000355         NULL            R003247         1
R003247         R000355         R000002         1
R000002         R003247         NULL            1
R004853         NULL            R028636         2
R004853         NULL            R028638         2
R004853         NULL            R028637         2
R028636         R004853         NULL            2
R028638         R004853         NULL            2
R028637         R004853         NULL            2

这个问题没什么可怕的,一旦你在手机上打字太多,给自己造成腕管。这只是一个稍加修改的标准递归层次查询问题。注意,递归中的连接条件是当前帐号是某个父帐户的子帐户。至于编号,我们只在顶级父级上使用
densite\u-RANK

WITH cte AS (
    SELECT m.*, DENSE_RANK() OVER (ORDER BY m.Account_Number) AS pos
    FROM temptable m
    WHERE Parent_Account IS NULL
    UNION ALL
    SELECT m.*, cte.pos
    FROM temptable m
    INNER JOIN cte
        ON m.Account_Number = cte.Child_Account
)

SELECT *
FROM cte
ORDER BY pos;


注:我非常感谢这里公认的精彩答案。

前三行
。。。除非提供生成此订单的
orderby
子句,否则这是没有意义的。SQL表与Excel中的表有点不同。@TimBiegeleisen我添加的
(如上表所示)
足以让读者知道我指的是问题中发布的表吗?这很棘手,我可以通过预期的输出+1计算出您想要什么。您需要一个递归的分层查询。我不知道怎么做:-(可能会在这里发现一些有用的东西:您的表让我抓狂。您有一行表示子表,另一行表示父表,这是多余的。您在这里遇到困难的主要原因是数据结构没有尽可能规范化。您有一个多对多关系,都被塞进了一个表中。谢谢,这只是说明了sql还有很多需要学习的地方。@ScottCraner这些问题在堆栈溢出时并不经常出现,因此您花了一些时间才得到答案。