bugfix> 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)

この表は、アカウント番号の分割と再割り当てを示しています。土地区画の分割と組み合わせの追跡に関係しています。

上記の表に示すように、最初の3行はグループ化する必要があります。これは、 R000355 から始まるためです。->  R003247 ->  R000002

上の表に示すように、最後の6も R004853 を示すため、グループ化する必要があります3つの R028636 に分割される 、 R028637R028638

私はこのようなものの多くのバリエーションを試しました:

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 件
  • 一度飛び込んで、手根管を携帯電話に打ちすぎないようにしたら、この質問について何も怖いことはありません。これは、わずかに変更された標準的な再帰的階層クエリの問題です。注目すべきは、再帰の結合条件は、現在のアカウント番号が親の子アカウントであることです。番号付けに関しては、 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;
    
    

    デモ

    注:ここでは、@ Quassnoiによって書かれた素晴らしい受け入れられた回答に多大な功績があります。

あなたの答え