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.

 

Últimas entradas de Javier Loria (ver todo)