Consulta SQL de agregado

23/01/2009 - 21:22 por José Antonio Muñoz | Informe spam
Hola al grupo,

Tengo una tabla con varios campos, uno de ellos, el valor se repite y otro
campo de tipo nvarchar(4) contiene un código, ¿Como puedo obtener una
consulta agrupando las filas por el campo que se repite y concatenado los
valores del campo de tipo carácter formando una cadena más larga?

Inicialmente la tabla tendría:
Campo1 Campo2
-
1 AB
2 AB
2 CD
3 EF
4 GH
4 KL

Al agrupar tendría:
Campo1 Campo2
1 AB
2 ABCD
3 EF
4 GHKL

Saludos,
José Antonio Muñoz

Preguntas similare

Leer las respuestas

#1 Carlos M. Calvelo
23/01/2009 - 22:14 | Informe spam
Hola José Antonio,

On 23 jan, 21:22, José Antonio Muñoz
wrote:
Hola al grupo,

Tengo una tabla con varios campos, uno de ellos, el valor se repite y otro
campo de tipo nvarchar(4) contiene un código, ¿Como puedo obtener una
consulta agrupando las filas por el campo que se repite y concatenado los
valores del campo de tipo carácter formando una cadena más larga?

Inicialmente la tabla tendría:
Campo1 Campo2
-
1 AB
2 AB
2 CD
3 EF
4 GH
4 KL

Al agrupar tendría:
Campo1 Campo2
1 AB
2 ABCD
3 EF
4 GHKL




Puedes crear una función; algo así:

create function concatCampo2(@cmp1 int) returns varchar(512)
as
begin
declare @res varchar(512)

set @res=''
select @res = @res + rtrim(campo2)
from tabla
where campo1 = @cmp1

return @res
end

Y luego utilizarla así:

select campo1, dbo.concatCampo2(campo1) as loquetuquieras
from tabla
group by campo1

Saludos,
Carlos
Respuesta Responder a este mensaje
#2 Alejandro Mesa
24/01/2009 - 00:01 | Informe spam
José Antonio Muñoz,

Cual es el orden en que se debe concatenar los valores Campo2 por cada grupo?

Si te das cuenta, el unico orden que podemos usar es "order by Campo".

Si trabajas con SS 2005 / 2008, puedes usar la clausula "FOR XML PATH ..."

CREATE TABLE #t (
Campo1 INT,
Campo2 VARCHAR(4)
)

INSERT INTO #t VALUES(1,'AB')
INSERT INTO #t VALUES(2,'AB')
INSERT INTO #t VALUES(2,'CD')
INSERT INTO #t VALUES(3,'EF')
INSERT INTO #t VALUES(4,'GH')
INSERT INTO #t VALUES(4,'KL')
GO

SELECT DISTINCT
Campo1,
(
SELECT CAST('' AS VARCHAR(MAX)) + Campo2
FROM #t AS b
WHERE b.Campo1 = a.Campo1
ORDER BY Campo2
FOR XML PATH('')
) AS Campo2
FROM
#t AS a
GO

DROP TABLE #t
GO


Concatenating row values in Transact-SQL
http://www.projectdmx.com/tsql/rowconcatenate.aspx


AMB


"José Antonio Muñoz" wrote:

Hola al grupo,

Tengo una tabla con varios campos, uno de ellos, el valor se repite y otro
campo de tipo nvarchar(4) contiene un código, ¿Como puedo obtener una
consulta agrupando las filas por el campo que se repite y concatenado los
valores del campo de tipo carácter formando una cadena más larga?

Inicialmente la tabla tendría:
Campo1 Campo2
-
1 AB
2 AB
2 CD
3 EF
4 GH
4 KL

Al agrupar tendría:
Campo1 Campo2
1 AB
2 ABCD
3 EF
4 GHKL

Saludos,
José Antonio Muñoz


Respuesta Responder a este mensaje
#3 José Antonio Muñoz
24/01/2009 - 18:01 | Informe spam
Gracias por vuestras respuestas, he resuelto el problema.

Como veo que teneis una mente privilegiada a ver si sois capaces de resolver
otro planteamiento (perdonad por mi insistencia pero tengo que hacer una
aplicación en SQL server planteando estos problemas).

Tengo la lista, más ampliada, del problema anterior:

Campo1 campo2

1 AB
2 ABCD
3 EF
4 GHKL
5 GHKL
6 AB
7 AB
8 ABCDKN
9 EF

como puedo calcular un nuevo campo (Campo3) que me indique cuando un valor
se está repitiendo o está variando con respecto del valor de la fila
anterior, es decir:

Campo 3 Campo1 Campo2

CV 1 AB
CV 2 ABCD
CV 3 EF
CV 4 GHKL
RV 5 GHKL
RV 6 GHKL
CV 6 AB
RV 7 AB
CV 8 ABCDKN
CV 9 EF

Donde CV=Cambia Valor y RV=Repite Valor

NOTA: La primera línea siempre debe comenzar con CV ya que no hay referencia
de un valor anterior. Y por supuesto la lista debe seguir el orden de
Campo1.

Saludos,
José Antonio Muñoz

"Alejandro Mesa" escribió en el
mensaje news:
José Antonio Muñoz,

Cual es el orden en que se debe concatenar los valores Campo2 por cada
grupo?

Si te das cuenta, el unico orden que podemos usar es "order by Campo".

Si trabajas con SS 2005 / 2008, puedes usar la clausula "FOR XML PATH ..."

CREATE TABLE #t (
Campo1 INT,
Campo2 VARCHAR(4)
)

INSERT INTO #t VALUES(1,'AB')
INSERT INTO #t VALUES(2,'AB')
INSERT INTO #t VALUES(2,'CD')
INSERT INTO #t VALUES(3,'EF')
INSERT INTO #t VALUES(4,'GH')
INSERT INTO #t VALUES(4,'KL')
GO

SELECT DISTINCT
Campo1,
(
SELECT CAST('' AS VARCHAR(MAX)) + Campo2
FROM #t AS b
WHERE b.Campo1 = a.Campo1
ORDER BY Campo2
FOR XML PATH('')
) AS Campo2
FROM
#t AS a
GO

DROP TABLE #t
GO


Concatenating row values in Transact-SQL
http://www.projectdmx.com/tsql/rowconcatenate.aspx


AMB


"José Antonio Muñoz" wrote:

Hola al grupo,

Tengo una tabla con varios campos, uno de ellos, el valor se repite y
otro
campo de tipo nvarchar(4) contiene un código, ¿Como puedo obtener una
consulta agrupando las filas por el campo que se repite y concatenado los
valores del campo de tipo carácter formando una cadena más larga?

Inicialmente la tabla tendría:
Campo1 Campo2
-
1 AB
2 AB
2 CD
3 EF
4 GH
4 KL

Al agrupar tendría:
Campo1 Campo2
1 AB
2 ABCD
3 EF
4 GHKL

Saludos,
José Antonio Muñoz


Respuesta Responder a este mensaje
#4 Carlos M. Calvelo
24/01/2009 - 20:38 | Informe spam
Hola José Antonio,

On 24 jan, 18:01, "José Antonio Muñoz"
wrote:
Gracias por vuestras respuestas, he resuelto el problema.

Como veo que teneis una mente privilegiada a ver si sois capaces de resolver
otro planteamiento (perdonad por mi insistencia pero tengo que hacer una
aplicación en SQL server planteando estos problemas).

Tengo la lista, más ampliada, del problema anterior:

Campo1 campo2

1 AB
2 ABCD
3 EF
4 GHKL
5 GHKL
6 AB
7 AB
8 ABCDKN
9 EF

como puedo calcular un nuevo campo (Campo3) que me indique cuando un valor
se está repitiendo o está variando con respecto del valor de la fila
anterior, es decir:

Campo 3 Campo1 Campo2

CV 1 AB
CV 2 ABCD
CV 3 EF
CV 4 GHKL
RV 5 GHKL
RV 6 GHKL
CV 6 AB
RV 7 AB
CV 8 ABCDKN
CV 9 EF

Donde CV=Cambia Valor y RV=Repite Valor

NOTA: La primera línea siempre debe comenzar con CV ya que no hay referencia
de un valor anterior. Y por supuesto la lista debe seguir el orden de
Campo1.




Veo que en tu ejemplo en las la líneas

RV 6 GHKL
CV 6 AB

el 6 se repite para Campo1. Supongo que la primera de estas dos
línias no debería estar ahí.
Entonces queda:

Campo 3 Campo1 Campo2

CV 1 AB
CV 2 ABCD
CV 3 EF
CV 4 GHKL
RV 5 GHKL
CV 6 AB
RV 7 AB
CV 8 ABCDKN
CV 9 EF

Si no es así, entonces no entiendo.

Bien. Como bien ha dicho Alejandro en el primer problema, el
resultado de la concatenación dependende del orden. Ahora
con este segundo problema se ve porqué eso es importante.
Vamos, que si usas la función que he puesto yo antes, tienes
que añadir un 'order by campo2' al select en la función.
Ten cuidado también con el varchar(512) que he puesto yo allí.
Quizás pueda una concatenación resultar en una cadena mucho
mas larga!? (Puedes cambiarlo a varchar(8000). )


Siguiendo ahora con esa función, y partiendo de la tabla en el
problema original, podemos hacer lo siguiente:

select case (select top 1 dbo.concatCampo2(campo1)
from tabla
where campo1 < t.campo1
order by campo1 desc)
when campo2 then 'RV' else 'CV' end as campo3,
campo1, campo2
from (select campo1, dbo.concatCampo2(campo1) as campo2
from tabla
group by campo1) t
order by campo1

Como ves la tabla en el from es la misma consulta del problema
anterior. La consulta 'exterior' solo añade otra columna (campo3)
que determina si campo2 ha cambiado respecto al campo2 del
registro con el mayor valor en campo1 de todos aquellos con
campo1 menor al del registro 'actual'.
(Espero se entienda esta explicación tipo rompecabezas)

Saludos,
Carlos
Respuesta Responder a este mensaje
#5 José Antonio Muñoz
25/01/2009 - 15:30 | Informe spam
Carlos y Alejandro, muchas gracias por todo, he resuelto el problema.

Saludos,
José antonio Muñoz

"Carlos M. Calvelo" escribió en el mensaje
news:
Hola José Antonio,

On 24 jan, 18:01, "José Antonio Muñoz"
wrote:
Gracias por vuestras respuestas, he resuelto el problema.

Como veo que teneis una mente privilegiada a ver si sois capaces de
resolver
otro planteamiento (perdonad por mi insistencia pero tengo que hacer una
aplicación en SQL server planteando estos problemas).

Tengo la lista, más ampliada, del problema anterior:

Campo1 campo2

1 AB
2 ABCD
3 EF
4 GHKL
5 GHKL
6 AB
7 AB
8 ABCDKN
9 EF

como puedo calcular un nuevo campo (Campo3) que me indique cuando un valor
se está repitiendo o está variando con respecto del valor de la fila
anterior, es decir:

Campo 3 Campo1 Campo2

CV 1 AB
CV 2 ABCD
CV 3 EF
CV 4 GHKL
RV 5 GHKL
RV 6 GHKL
CV 6 AB
RV 7 AB
CV 8 ABCDKN
CV 9 EF

Donde CV=Cambia Valor y RV=Repite Valor

NOTA: La primera línea siempre debe comenzar con CV ya que no hay
referencia
de un valor anterior. Y por supuesto la lista debe seguir el orden de
Campo1.




Veo que en tu ejemplo en las la líneas

RV 6 GHKL
CV 6 AB

el 6 se repite para Campo1. Supongo que la primera de estas dos
línias no debería estar ahí.
Entonces queda:

Campo 3 Campo1 Campo2

CV 1 AB
CV 2 ABCD
CV 3 EF
CV 4 GHKL
RV 5 GHKL
CV 6 AB
RV 7 AB
CV 8 ABCDKN
CV 9 EF

Si no es así, entonces no entiendo.

Bien. Como bien ha dicho Alejandro en el primer problema, el
resultado de la concatenación dependende del orden. Ahora
con este segundo problema se ve porqué eso es importante.
Vamos, que si usas la función que he puesto yo antes, tienes
que añadir un 'order by campo2' al select en la función.
Ten cuidado también con el varchar(512) que he puesto yo allí.
Quizás pueda una concatenación resultar en una cadena mucho
mas larga!? (Puedes cambiarlo a varchar(8000). )


Siguiendo ahora con esa función, y partiendo de la tabla en el
problema original, podemos hacer lo siguiente:

select case (select top 1 dbo.concatCampo2(campo1)
from tabla
where campo1 < t.campo1
order by campo1 desc)
when campo2 then 'RV' else 'CV' end as campo3,
campo1, campo2
from (select campo1, dbo.concatCampo2(campo1) as campo2
from tabla
group by campo1) t
order by campo1

Como ves la tabla en el from es la misma consulta del problema
anterior. La consulta 'exterior' solo añade otra columna (campo3)
que determina si campo2 ha cambiado respecto al campo2 del
registro con el mayor valor en campo1 de todos aquellos con
campo1 menor al del registro 'actual'.
(Espero se entienda esta explicación tipo rompecabezas)

Saludos,
Carlos
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida