Làm cách nào tôi có thể nhận được các giá trị phân cấp từ truy vấn bên dưới?


8

Tôi có một bảng được đặt tên Categorycó một cột được đặt tên CategoryID. Có một cột tham chiếu trong cùng một bảng được gọi fParentCategoryID.

Tôi cần lấy tất cả các ID danh mục và ID danh mục con của chúng được phân tách bằng dấu phẩy. Ví dụ: nếu ID danh mục cha mẹ của 10 là 1 và nếu Id danh mục chính của 20 là 10 thì khi tôi in ID danh mục 20, tôi cần in cả 1 và 10 dưới dạng cha mẹ của nó trong các giá trị được phân tách bằng dấu phẩy.

Tôi đã thử truy vấn dưới đây nhưng tôi nhận được NULLcho ParChildcột. Xin vui lòng giúp đỡ.

;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 

sử dụng tập lệnh này để tạo và điền vào bảng. (lưu ý: có giới hạn 30K cho phần thân câu hỏi. Vì vậy, tôi đã phải sử dụng pastebin để sao chép mã của bạn và tham chiếu nó)

Câu trả lời:


3

Tôi đã có thể sao chép kết quả của bạn với dữ liệu mẫu của bạn.

Vấn đề của bạn là trong trường hợp "cơ sở" của CTE đệ quy (câu lệnh chọn đầu tiên), bạn sẽ nhận được các bản ghi trong đó fParentC CategoryID là null và chuyển fParentCargetID sang cột ký tự sẵn sàng để thêm "trẻ em". Tuy nhiên, 'chuỗi' vẫn là một giá trị NULL ở giai đoạn này (thử nó với CHỌN CAST (NULL AS VARCHAR (200)) hoặc tương tự).

Câu lệnh chọn thứ hai sau đó cố gắng nối các giá trị chuỗi khác vào NULL nhưng theo mặc định, tùy chọn cơ sở dữ liệu "concat null mang lại null" cho biết nếu bạn cố nối bất cứ thứ gì với giá trị NULL thì bạn vẫn chỉ nhận được NULL - chứ không phải coi nó là một chuỗi rỗng.

Bạn có thể THIẾT LẬP CONCAT_NULL_YIELDS_NULL TẮT cho truy vấn này mặc dù điều này không được chấp nhận và cuối cùng sẽ bị xóa trong phiên bản SQL Server trong tương lai (vì vậy có lẽ bạn không nên thêm nó vào mã sản xuất!)

Một cách tốt hơn là trong câu lệnh chọn đầu tiên, thay vì truyền fParentC CategoryID thành một chuỗi, chỉ cần truyền CategoryID - chúng ta đã biết cha mẹ nên trống vì chúng là 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

Nếu dữ liệu của bạn có thể có hỗn hợp các giá trị null và không null trong câu lệnh chọn đó, bạn cũng có thể sử dụng ISNULL xung quanh nó để coi bất kỳ null nào là chuỗi rỗng.

Nó có thể cần một số dọn dẹp trên giá trị ParChild mà nó tạo ra khi bạn nhận được các giá trị như ", 461,464" vì vậy bạn có thể muốn loại bỏ dấu phẩy bắt đầu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.