以下のクエリから階層値を取得するにはどうすればよいですか?


8

という名前Categoryの列を持つテーブルという名前のテーブルがありますCategoryID。と呼ばれる同じテーブルに参照列がありますfParentCategoryID

すべてのカテゴリIDとそのサブカテゴリIDをカンマで区切る必要があります。 -10の親カテゴリIDが1で、20の親カテゴリIDが10の場合、カテゴリID 20を印刷するとき、1と10の両方を親としてカンマ区切り値で印刷する必要があります。

以下のクエリを試してみましたがNULLParChild列が表示されます。助けてください。

;WITH
  cteReports 
  AS
(
SELECT c.CategoryID,
       c.fParentCategoryID,
       [level] = 1,
       ParChild=cast(CAST(c.fParentCategoryID AS VARCHAR(200)) + ',' + CAST(c.CategoryID AS VARCHAR(200)) AS VARCHAR(MAX))
FROM   retail.Category c
WHERE c.fParentCategoryID is NULL
UNION ALL
SELECT c.CategoryID,
       c.fParentCategoryID,
       [level] + 1,
       ParChild = ParChild + ',' + CAST(c.CategoryID AS VARCHAR(200))
FROM   retail.Category c
        JOIN cteReports r
            ON  c.fParentCategoryID = r.CategoryID

)

SELECT *
FROM   cteReports cr 

使用このスクリプトを作成して、テーブルを移入します。 (注:質問の本文には30Kの制限があります。そのため、ペーストビンを使用してコードをコピーして参照する必要がありました)

回答:


3

あなたの例のデータであなたの結果を再現することができました。

問題は、再帰CTE(最初の選択ステートメント)の「ベース」の場合、fParentCategoryIDがnullであるレコードを取得し、fParentCategoryIDを文字列にキャストして、「子」を追加する準備ができていることです。ただし、この段階ではまだ 'string'はNULL値です(SELECT CAST(NULL AS VARCHAR(200))などで試してください)。

2番目の選択ステートメントは、他の文字列値をNULLに追加しようとしますが、デフォルトでは、データベースオプション「concat nullはnullを生成します」は、何かをNULL値に連結しようとすると、NULLを取得するだけでなく、空の文字列。

このクエリにはCONCAT_NULL_YIELDS_NULL OFFを設定できますが、これは非推奨であり、SQL Serverの将来のバージョンでは最終的に削除されます(したがって、本番用コードに追加しないでください!)

より良い方法は、fParentCategoryIDを文字列にキャストするのではなく、最初のselectステートメントを使用することです。CategoryIDをキャストするだけです。親はNULLであるため、空である必要があります。

SELECT c.CategoryID,
   c.fParentCategoryID,
   [level] = 1,
   ParChild=cast(CAST(c.CategoryID AS VARCHAR(200)) AS VARCHAR(MAX))
FROM   retail.Category c
WHERE c.fParentCategoryID is NULL

そのselectステートメントでデータにnull値とnull以外の値が混在している可能性がある場合は、ISNULLを使用してnullを空の文字列として扱うこともできます。

"、461,464"のような値を取得するときに生成されるParChild値のクリーンアップが必要になる可能性があるため、最初のコンマを削除する必要がある場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.