¿Cómo puedo obtener los valores jerárquicos de la consulta a continuación?

8

Tengo una tabla llamada Categoryque tiene una columna llamada CategoryID. Hay una columna de referencia en la misma tabla llamada fParentCategoryID.

Necesito obtener todos los ID de categoría y sus ID de subcategoría separados por comas. Por ejemplo: si el ID de categoría principal de 10 es 1 y si el ID de categoría principal de 20 es 10, cuando imprimo el ID de categoría 20 necesito imprimir 1 y 10 como sus padres en valores separados por comas.

Probé el siguiente consulta, pero me sale NULLde ParChildla columna. Por favor ayuda.

;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 

use este script para crear y completar la tabla. (nota: hay un límite de 30K para el cuerpo de la pregunta ... Así que tuve que usar pastebin para copiar su código y hacer referencia a él)

mayooran
fuente

Respuestas:

3

Pude replicar sus resultados con sus datos de ejemplo.

Su problema es que, en el caso "base" del CTE recursivo (la primera instrucción de selección), obtiene los registros donde fParentCategoryID es nulo y convierte el fParentCategoryID en una columna de caracteres lista para agregar los "hijos". Sin embargo, la 'cadena' sigue siendo un valor NULL en esta etapa (pruébelo con SELECT CAST (NULL AS VARCHAR (200)) o similar).

La segunda instrucción select luego intenta agregar otros valores de cadena al NULL, pero de forma predeterminada, la opción de base de datos "concat null produce null" dice que si intenta concatenar algo a un valor NULL, entonces solo obtiene NULL, en lugar de tratarlo como Una cadena vacía.

Puede ESTABLECER CONCAT_NULL_YIELDS_NULL OFF para esta consulta, aunque está en desuso y finalmente se eliminará en una versión futura de SQL Server (¡así que probablemente no debería agregarlo al código de producción!)

Una mejor manera es en la primera instrucción select, en lugar de convertir el fParentCategoryID en una cadena, simplemente convierta el CategoryID; ya sabemos que el padre debe estar vacío, ya que son 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

Si sus datos pueden tener una mezcla de valores nulos y no nulos en esa instrucción select, también puede usar ISNULL a su alrededor para tratar los nulos como cadenas vacías.

Probablemente necesite una limpieza en el valor de ParChild que produce a medida que obtiene valores como ", 461,464", por lo que es posible que desee quitar la coma inicial.

setenta y ocho
fuente