创建链接ID

时间:2018-05-25 14:32:30

标签: 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

可以加载:

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被分为三个R028636R028637R028638。< / p>

我尝试了很多这样的变体:

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

1 个答案:

答案 0 :(得分: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;

Demo

注意:我非常赞赏这里精彩的答案written by @Quassnoi