创建关联 ID

Sco*_*ner 5 sql-server

我有下表:

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
Run Code Online (Sandbox Code Playgroud)

可以加载:

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)
Run Code Online (Sandbox Code Playgroud)

此表表示帐号的拆分和重新分配。它与跟踪地块的分割和组合有关。

前三行,如上表所示,应该组合在一起,因为它来自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
Run Code Online (Sandbox Code Playgroud)

其中产生了:

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
Run Code Online (Sandbox Code Playgroud)

当我真正需要的是:

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
Run Code Online (Sandbox Code Playgroud)

Tim*_*sen 3

这个问题没什么可怕的,一旦你跳进去并因为在手机上打字太多而让自己腕管受伤。这只是一个稍微修改的标准递归分层查询问题。值得注意的是,递归中的连接条件是当前帐号是某个家长的子帐号。至于编号,我们只使用DENSE_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;
Run Code Online (Sandbox Code Playgroud)

演示

注意:我对@Quassnoi 撰写的出色的公认答案给予高度赞扬。