2

次のデータを含む階層テーブルがあります。

SOURCE  TARGET  Level   ID
0       1       1       1
0       2       1       2
2       3       2       3
2       4       2       4
2       5       2       5
1       3       2       6
1       4       2       7
1       5       2       8
5       3       3       9
5       3       3       10
4       3       3       11
4       3       3       12
3       6       3       13
3       6       3       14
3       6       4       15
3       6       4       16
3       6       4       17
3       6       4       18

SOURCE 行と TARGET 行は元のデータであり、親と子を接続するために使用されます。たとえば、3 番目の行 (SOURCE 2、LEVEL 2 の TARGET 3) は 2 番目の行 (SOURCE 0、LEVEL 1 の TARGET 2) に接続します。これは、最初の行のソースが 2 番目のターゲットと等しいためです。
ID 列は、ROW_NUMBER 関数を使用して最後に追加され、各行に一意の ID を付与するために使用されます。
SOURCE を PARENT に、TARGET を CHILD に置き換えるとわかりやすいかもしれません。

「親」を見つけるために、テーブルをそれ自体に結合します。
各レベルの「ソース」の各「インスタンス」がその親の 1 つに接続するようにします。どちらが接続されるかは重要ではありませんが、すべてが接続され、異なる親に接続される必要があります。

最終結果は次のようになります。

SOURCE  TARGET  Level   ID   P_ID
0       1       1       1    NULL
0       2       1       2    NULL
2       3       2       3    2
2       4       2       4    2
2       5       2       5    2
1       3       2       6    1
1       4       2       7    1
1       5       2       8    1
5       3       3       9    5
5       3       3       10   8
4       3       3       11   4
4       3       3       12   7
3       6       3       13   3
3       6       3       14   6
3       6       4       15   9
3       6       4       16   10
3       6       4       17   11
3       6       4       18   12

これに適した ms-sql クエリを作成する方法について何か提案はありますか?

4

1 に答える 1

3

サンプル データとSQL Fiddleへのリンク

使用するクエリは次のとおりです。

;with cte as (
  select *,rn=row_number() over (partition by level, target
                                 order by id),
           lc=count(1) over (partition by level, target)
  from tbl
)

select a.*, b.id as parent_id
from cte a
left join cte b on b.level=a.level-1
               and b.target=a.source
               and b.rn=(a.rn-1)%b.lc+1
order by id
  1. 項目は各レベル/ターゲットの組み合わせで順序付けられます
  2. 子はシーケンスを使用して親にリンクされますが、親より子が多い場合は、MOD (%) 演算子が最初の親に戻って配布を続行します。
于 2012-10-09T09:34:41.610 に答える