miércoles, 3 de septiembre de 2014

CONCATENAR USANDO FOR XML PATH Y STUFF

 En el foro de SQL SERVER se cuestiona mucho como concatenar varias filas en una sola, sobre todo esto se utiliza para evitar el uso de los cursores y es mucho más rápido, para comenzar es necesario la tabla AdventureWorks2012.
?
1
2
SELECT TOP 10 FirstName
FROM AdventureWorks2012.Person.Person

Hasta aquí no hay nada, digámoslo de cierta forma, nuevo, pero para poder hacer la concatenación requerimos de la función STUFF y la clausula FOR XML utilizando el modo PATH.
La función STUFF sirve para ingresar una cadena en otra a partir de los parámetros de posición y longitud. Siendo de esta manera, el siguiente ejemplo:
?
1
2
SELECT TOP 10 FirstName, STUFF( FirstName, 3,2,'CADENA') as resultado
FROM AdventureWorks2012.Person.Person
Lo que nos arroja como resultado:
Y para que funciona FOR XML PATH, para devolver una consulta en formato XML, este es el resultado de una consulta a la base de datos AdventureWorks2012:
?
1
2
3
SELECT TOP 3 FirstName, MiddleName, LastName LastName
FROM AdventureWorks2012.Person.Person
FOR XML PATH
Y si damos click al resultado, nos muestra esto:
Si agregamos el parámetro, reemplazara el atributo de fila:
?
1
2
3
SELECT TOP 3 FirstName, MiddleName, LastName LastName
FROM AdventureWorks2012.Person.Person
FOR XML PATH('FILA')
Y que pasa si establecemos un valor vacío?:
Combinando STUFF y FOR XML PATH, podemos lograr concatenar las filas.
?
1
2
3
4
5
SELECT STUFF((
       SELECT TOP 10 ','+FirstName
       FROM AdventureWorks2012.Person.Person
       FOR XML PATH('')
),1,1, '')
Y de esta manera es posible agrupar a un nivel superior:
?
1
2
3
4
5
6
7
8
9
SELECT
       PC.Name
       ,STUFF((
             SELECT ','+name
             FROM Production.ProductSubcategory PSC
             WHERE PSC.ProductCategoryID = PC.ProductCategoryID
             FOR XML PATH('')
       ),1,1,'')
FROM Production.ProductCategory PC
Algo más complejo, observemos las tablas Sales.SpecialOffer, Sales.SpecialOfferProduct,Production.Product, la primera contiene las ofertas especiales( como su nombre lo indica), la segunda tabla contiene el detallado de los productos que por cada oferta especial y la tercera el detallado de los productos. Lo que queremos obtener es todos los productos de cada oferta especial:

Sales.SpecialOffer:
Sales.SpecialOfferProduct:
Production.Product
La consulta quedaría así:
?
1
2
3
4
5
6
7
8
9
10
SELECT SO.SpecialOfferID, SO.Description
, STUFF((
       SELECT ','+p.Name
       FROM sales.SpecialOfferProduct SOP
       INNER JOIN Production.Product P
       ON SOP.ProductID = p.ProductID
       AND SOP.SpecialOfferID = SO.SpecialOfferID
       FOR XML PATH('')
),1,1,'' ) as productos
FROM Sales.SpecialOffer SO
Una forma muy practica y mucho mejor para concatenar valores en comparación que si utilizaramos un cursor.

Espero que les sirva.

Fuente: http://chancrovsky.blogspot.com/2013/04/concatenar-usando-for-xml-path-y-stuff.html

No hay comentarios:

Publicar un comentario