Bagaimana saya bisa mendapatkan nilai hierarkis dari kueri di bawah ini?

8

Saya memiliki tabel yang diberi nama Categorykolom CategoryID. Ada kolom referensi dalam tabel yang sama yang disebut fParentCategoryID.

Saya perlu memisahkan semua ID kategori dan ID subkategori mereka. Sebagai contoh - jika ID kategori induk 10 adalah 1 dan jika ID kategori induk 20 adalah 10 maka ketika saya mencetak ID kategori 20 saya perlu mencetak 1 dan 10 sebagai induknya dalam nilai yang dipisahkan koma.

Saya mencoba bawah permintaan tapi aku mendapatkan NULLuntuk ParChildkolom. Tolong bantu.

;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 

gunakan skrip ini untuk membuat dan mengisi tabel. (catatan: ada batas 30K ke badan pertanyaan..Jadi saya harus menggunakan pastebin untuk menyalin kode Anda dan referensi itu)

mayooran
sumber

Jawaban:

3

Saya dapat mereplikasi hasil Anda dengan contoh data Anda.

Masalah Anda adalah bahwa dalam kasus "dasar" CTE rekursif (pernyataan pilih pertama) Anda mendapatkan catatan di mana fParentCategoryID adalah nol dan melemparkan fParentCategoryID ke kolom karakter yang siap untuk menambahkan "anak-anak". Namun 'string' masih merupakan nilai NULL pada tahap ini (coba dengan SELECT CAST (NULL AS VARCHAR (200)) atau sejenisnya).

Pernyataan pilih kedua kemudian mencoba untuk menambahkan nilai string lain ke NULL tetapi secara default, opsi database "concat null menghasilkan null" mengatakan jika Anda mencoba menggabungkan sesuatu ke nilai NULL maka Anda masih mendapatkan NULL - daripada memperlakukannya sebagai NULL - daripada memperlakukannya sebagai string kosong.

Anda bisa SET CONCAT_NULL_YIELDS_NULL OFF untuk permintaan ini meskipun ini sudah usang dan pada akhirnya akan dihapus dalam versi SQL Server yang akan datang (jadi Anda mungkin tidak boleh menambahkannya ke kode produksi!)

Cara yang lebih baik adalah pada pernyataan pilih pertama, alih-alih melemparkan fParentCategoryID ke string, cukup masukkan CategoryID - kita sudah tahu bahwa induknya harus kosong karena mereka adalah 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

Jika data Anda dapat memiliki campuran nilai null dan non null dalam pernyataan pilih itu, Anda juga bisa menggunakan ISNULL di sekitarnya untuk memperlakukan setiap null sebagai string kosong.

Mungkin perlu beberapa pembersihan pada nilai ParChild yang dihasilkannya saat Anda mendapatkan nilai seperti ", 461.464" sehingga Anda mungkin ingin menghapus koma awal.

sevenyeightist
sumber