En un posteo reciente use un “patrón” de comando de SQL que tiene la siguiente forma:

SET @Comando=
SELECT TOP 10 @Comando=@Comando+CHAR(13)+CHAR(10)+Indice
FROM dbo.FragmentacionIndices
ORDER BY TotalPages DESC;

Este comando permite concatenar un texto usando una variable, pero mi amigo Eladio Rincón, que el equipo de desarrollo de SQL, sostiene que ese comando no está garantizado que brinda resultados consistentes.

Ahora para otro proyecto tengo que concatenar una de nombres que están relacionados con una tabla. Despues de estudiar algunas alternativas me gusta la siguiente solución:

; WITH ProveedoresOrdenados (ProductID, VendorId, NumProveedor) AS

(

SELECT ProductVendor.ProductID

    , ProductVendor.VendorID

    , ROW_NUMBER() OVER ( PARTITION BY ProductID ORDER BY VendorID) AS NumProveedor

FROM Purchasing.ProductVendor

)

, ProdVendedorRecursivo (ProductId, VendorId, Description, NumProveedor)

AS (

    SELECT ProveedoresOrdenados.ProductID

        , ProveedoresOrdenados.VendorId

        , CAST(ProveedoresOrdenados.VendorID AS VARCHAR(8000))

        , ProveedoresOrdenados.NumProveedor

    FROM ProveedoresOrdenados

    WHERE NumProveedor=1

UNION ALL

SELECT ProveedoresOrdenados.ProductId, ProveedoresOrdenados.VendorId

, ProdVendedorRecursivo.Description + ‘, ‘ + CAST(ProveedoresOrdenados.VendorId AS VARCHAR(8000))

, ProveedoresOrdenados.NumProveedor

     FROM ProveedoresOrdenados

     JOIN ProdVendedorRecursivo

     ON ProveedoresOrdenados.ProductID=ProdVendedorRecursivo.ProductId

        AND ProveedoresOrdenados.NumProveedor=ProdVendedorRecursivo.NumProveedor+1

)

SELECT ProdVendedorRecursivo.ProductId, ProdVendedorRecursivo.Description

FROM ProdVendedorRecursivo

JOIN (SELECT ProductId, MAX(ProdVendedorRecursivo.NumProveedor) AS NumProveedor

FROM ProdVendedorRecursivo GROUP BY ProductId) AS Last

ON ProdVendedorRecursivo.ProductId=Last.ProductId

AND ProdVendedorRecursivo.NumProveedor=Last.NumProveedor

 

El ejemplo se basa en la BD de AdventureWorks y la tabla ProductVendors. ProductVendors es captura una relación de muchos a muchos entre Products y Vendors el comando pretende obtener para cada producto una columna con la lista de Proveedores (Vendors).

El comando usa 2 CTEs y algunas funciones disponibles desde SQL 2005 para obtener el resultado deseado. La primera consulta usa ROW_NUMBER para obtener un número consecutivo de proveedor para cada producto, este número facilita los JOINS de la segunda consulta. La segunda consulta aprovecha las consultas recursivas para concatenar la descripción, de manera tal que cada línea tiene la descripción de todos los anteriores. Finalmente la consulta filtra y despliega solo la última fila de cada producto.

No estoy seguro de su desempeño en tablas de tamaño considerable.

 

0 Shares:
Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like
Leer más

Extended support. Pan para hoy, hambre para mañana.

Este año 2020 va a representar un reto importante para muchas organizaciones desde el punto de vista de actualizaciones/renovaciones. El soporte extendido de SQL Server 2008 terminaba el pasado 9 de Julio de 2019 y hoy 14 de Enero de 2020 termina el de Windows Server 2008 y 2008 R2. Muchas empresas son conscientes del fin de soporte y a pesar de ello, aún no tienen prevista la migración por lo que probablemente deba ser abordada en breve y con cierta urgencia (escanario ideal).