Ayuda Pivot

23/10/2006 - 17:35 por Paco | Informe spam
Hola

Necesito hacer una consulta con PIVOT creando las columnas de forma dinámica.
Os explico un poco lo que he hecho para que podais entender mejor el objetivo.

Tengo una tabla de movimientos de este tipo:

Fecha (k)
Producto (k)
Importe

Tengo otra tabla con los periodos a consultar :

Periodo (k)
FechaDesde
FechaHasta

Esta tabla se devuelve de una función y el tipo de periodo puede ser
dias,semanas,mes,año,decena,quincena,trimestre, etc...

Para hacer pivot he probado con este ejemplo:

SELECT Articulo, [15/2006], [16/2006] from
(
SELECT Periodos.Periodo, Movimientos.Articulo, Movimientos.Importe
FROM dbo.ListaPeriodos('SEMANA', @FDesde, @FHasta) AS Periodos
INNER JOIN
Movimientos ON Movimientos.Fecha >=
Periodos.FechaDesde AND
Movimientos.Fecha <= Periodos.FechaHasta
) p
pivot
(
sum(Importe) for titulo in ([15/2006],[16/2006]))
as pvt

Con esto consigo el siguiente resultado :

Articulo [15/2006] [16/2006]
1 125 250
2 135 365
3 0 52
4 50 26

He conseguido acercarme al objetivo pero siempre conociendo los valores de
las columnas de periodos.
Lo que me gustaría hacer es la misma consulta pero pudiendo cambiar los
periodos de forma dinámica, sin escribirlos en la sentencia PIVOT.

Si alguien se le ocurre como...

Preguntas similare

Leer las respuestas

#1 Javier Loria
23/10/2006 - 18:27 | Informe spam
Hola:
No existe forma de hacer esto, sin usar SQL Dinamico. Puedes revisar
http://www.hayes.ch/sql/sql_dinamico.html.
En todo caso si lo necesitas seria un codigo horrible, algo como:
ÞCLARE @Columna NVARCHAR(MAX);
DECLARE @Sentencia NVARCHAR(MAX);
SET @SeNtencia='SELECT *
from
(
SELECT Periodos.Periodo
, Movimientos.Articulo
, Movimientos.Importe
FROM dbo.ListaPeriodos(''SEMANA'', ' +
CONVERT(VARCHAR(8), @FDesde, 112) + ', '
+CONVERT(VARCHAR(8), @FHasta, 112)+ ')
AS Periodos
INNER JOIN Movimientos
ON Movimientos.Fecha >= Periodos.FechaDesde
AND Movimientos.Fecha <= Periodos.FechaHasta) p
PIVOT(SUM(Importe) for titulo in (';

WITH Fechas(Fecha)
AS
( SELECT CAST(@FDesde AS SMALLDATETIME)
UNION ALL
SELECT DATEADD(DAY, 1, Fecha)
FROM Fechas
WHERE Fecha<@FHasta
)
SELECT @Columna=COALESCE(@Columna+ ', ['+
CONVERT(VARCHAR(8), Fecha, 112)+']','['+CONVERT(VARCHAR(8), Fecha,
112)+']')
FROM Fechas;
SET @Sentencia=@Sentencia+@Columna+')) as pvt';

execute sp_executesql @Sentencia
== Saludos,


Javier Loria
Costa Rica-MVP
Solid Quality Learning

"Paco" wrote in message
news:
Hola

Necesito hacer una consulta con PIVOT creando las columnas de forma
dinámica.
Os explico un poco lo que he hecho para que podais entender mejor el
objetivo.

Tengo una tabla de movimientos de este tipo:

Fecha (k)
Producto (k)
Importe

Tengo otra tabla con los periodos a consultar :

Periodo (k)
FechaDesde
FechaHasta

Esta tabla se devuelve de una función y el tipo de periodo puede ser
dias,semanas,mes,año,decena,quincena,trimestre, etc...

Para hacer pivot he probado con este ejemplo:

SELECT Articulo, [15/2006], [16/2006] from
(
SELECT Periodos.Periodo, Movimientos.Articulo, Movimientos.Importe
FROM dbo.ListaPeriodos('SEMANA', @FDesde, @FHasta) AS Periodos
INNER JOIN
Movimientos ON Movimientos.Fecha >> Periodos.FechaDesde AND
Movimientos.Fecha <= Periodos.FechaHasta
) p
pivot
(
sum(Importe) for titulo in ([15/2006],[16/2006]))
as pvt

Con esto consigo el siguiente resultado :

Articulo [15/2006] [16/2006]
1 125 250
2 135 365
3 0 52
4 50 26

He conseguido acercarme al objetivo pero siempre conociendo los valores de
las columnas de periodos.
Lo que me gustaría hacer es la misma consulta pero pudiendo cambiar los
periodos de forma dinámica, sin escribirlos en la sentencia PIVOT.

Si alguien se le ocurre como...
Respuesta Responder a este mensaje
#2 Maxi
24/10/2006 - 03:49 | Informe spam
Exacto, una de las razones de porque esto funciona es asi es porque el pivot
de sql2005 es ANSI


Saludos

[Microsoft MVP SQL Server]
www.sqlgurus.org
Buenos Aires - Argentina
"Javier Loria" wrote in message
news:
Hola:
No existe forma de hacer esto, sin usar SQL Dinamico. Puedes revisar
http://www.hayes.ch/sql/sql_dinamico.html.
En todo caso si lo necesitas seria un codigo horrible, algo como:
=> DECLARE @Columna NVARCHAR(MAX);
DECLARE @Sentencia NVARCHAR(MAX);
SET @SeNtencia='SELECT *
from
(
SELECT Periodos.Periodo
, Movimientos.Articulo
, Movimientos.Importe
FROM dbo.ListaPeriodos(''SEMANA'', ' +
CONVERT(VARCHAR(8), @FDesde, 112) + ', '
+CONVERT(VARCHAR(8), @FHasta, 112)+ ')
AS Periodos
INNER JOIN Movimientos
ON Movimientos.Fecha >= Periodos.FechaDesde
AND Movimientos.Fecha <= Periodos.FechaHasta) p
PIVOT(SUM(Importe) for titulo in (';

WITH Fechas(Fecha)
AS
( SELECT CAST(@FDesde AS SMALLDATETIME)
UNION ALL
SELECT DATEADD(DAY, 1, Fecha)
FROM Fechas
WHERE Fecha<@FHasta
)
SELECT @Columna=COALESCE(@Columna+ ', ['+
CONVERT(VARCHAR(8), Fecha, 112)+']','['+CONVERT(VARCHAR(8), Fecha,
112)+']')
FROM Fechas;
SET @Sentencia=@Sentencia+@Columna+')) as pvt';

execute sp_executesql @Sentencia
==> Saludos,


Javier Loria
Costa Rica-MVP
Solid Quality Learning

"Paco" wrote in message
news:
Hola

Necesito hacer una consulta con PIVOT creando las columnas de forma
dinámica.
Os explico un poco lo que he hecho para que podais entender mejor el
objetivo.

Tengo una tabla de movimientos de este tipo:

Fecha (k)
Producto (k)
Importe

Tengo otra tabla con los periodos a consultar :

Periodo (k)
FechaDesde
FechaHasta

Esta tabla se devuelve de una función y el tipo de periodo puede ser
dias,semanas,mes,año,decena,quincena,trimestre, etc...

Para hacer pivot he probado con este ejemplo:

SELECT Articulo, [15/2006], [16/2006] from
(
SELECT Periodos.Periodo, Movimientos.Articulo, Movimientos.Importe
FROM dbo.ListaPeriodos('SEMANA', @FDesde, @FHasta) AS Periodos
INNER JOIN
Movimientos ON Movimientos.Fecha >>> Periodos.FechaDesde AND
Movimientos.Fecha <= Periodos.FechaHasta
) p
pivot
(
sum(Importe) for titulo in ([15/2006],[16/2006]))
as pvt

Con esto consigo el siguiente resultado :

Articulo [15/2006] [16/2006]
1 125 250
2 135 365
3 0 52
4 50 26

He conseguido acercarme al objetivo pero siempre conociendo los valores
de
las columnas de periodos.
Lo que me gustaría hacer es la misma consulta pero pudiendo cambiar los
periodos de forma dinámica, sin escribirlos en la sentencia PIVOT.

Si alguien se le ocurre como...




Respuesta Responder a este mensaje
#3 Paco
24/10/2006 - 10:42 | Informe spam
Muchas Gracias a los dos. Deduzco por vuestras respuestas que mis únicas
opciones para hacerlo son sql dinámico o programarlo en la capa de
presentación.


"Maxi" wrote:

Exacto, una de las razones de porque esto funciona es asi es porque el pivot
de sql2005 es ANSI


Saludos

[Microsoft MVP SQL Server]
www.sqlgurus.org
Buenos Aires - Argentina
"Javier Loria" wrote in message
news:
> Hola:
> No existe forma de hacer esto, sin usar SQL Dinamico. Puedes revisar
> http://www.hayes.ch/sql/sql_dinamico.html.
> En todo caso si lo necesitas seria un codigo horrible, algo como:
> => > DECLARE @Columna NVARCHAR(MAX);
> DECLARE @Sentencia NVARCHAR(MAX);
> SET @SeNtencia='SELECT *
> from
> (
> SELECT Periodos.Periodo
> , Movimientos.Articulo
> , Movimientos.Importe
> FROM dbo.ListaPeriodos(''SEMANA'', ' +
> CONVERT(VARCHAR(8), @FDesde, 112) + ', '
> +CONVERT(VARCHAR(8), @FHasta, 112)+ ')
> AS Periodos
> INNER JOIN Movimientos
> ON Movimientos.Fecha >= Periodos.FechaDesde
> AND Movimientos.Fecha <= Periodos.FechaHasta) p
> PIVOT(SUM(Importe) for titulo in (';
>
> WITH Fechas(Fecha)
> AS
> ( SELECT CAST(@FDesde AS SMALLDATETIME)
> UNION ALL
> SELECT DATEADD(DAY, 1, Fecha)
> FROM Fechas
> WHERE Fecha<@FHasta
> )
> SELECT @Columna=COALESCE(@Columna+ ', ['+
> CONVERT(VARCHAR(8), Fecha, 112)+']','['+CONVERT(VARCHAR(8), Fecha,
> 112)+']')
> FROM Fechas;
> SET @Sentencia=@Sentencia+@Columna+')) as pvt';
>
> execute sp_executesql @Sentencia
> ==> > Saludos,
>
>
> Javier Loria
> Costa Rica-MVP
> Solid Quality Learning
>
> "Paco" wrote in message
> news:
>> Hola
>>
>> Necesito hacer una consulta con PIVOT creando las columnas de forma
>> dinámica.
>> Os explico un poco lo que he hecho para que podais entender mejor el
>> objetivo.
>>
>> Tengo una tabla de movimientos de este tipo:
>>
>> Fecha (k)
>> Producto (k)
>> Importe
>>
>> Tengo otra tabla con los periodos a consultar :
>>
>> Periodo (k)
>> FechaDesde
>> FechaHasta
>>
>> Esta tabla se devuelve de una función y el tipo de periodo puede ser
>> dias,semanas,mes,año,decena,quincena,trimestre, etc...
>>
>> Para hacer pivot he probado con este ejemplo:
>>
>> SELECT Articulo, [15/2006], [16/2006] from
>> (
>> SELECT Periodos.Periodo, Movimientos.Articulo, Movimientos.Importe
>> FROM dbo.ListaPeriodos('SEMANA', @FDesde, @FHasta) AS Periodos
>> INNER JOIN
>> Movimientos ON Movimientos.Fecha >> >> Periodos.FechaDesde AND
>> Movimientos.Fecha <= Periodos.FechaHasta
>> ) p
>> pivot
>> (
>> sum(Importe) for titulo in ([15/2006],[16/2006]))
>> as pvt
>>
>> Con esto consigo el siguiente resultado :
>>
>> Articulo [15/2006] [16/2006]
>> 1 125 250
>> 2 135 365
>> 3 0 52
>> 4 50 26
>>
>> He conseguido acercarme al objetivo pero siempre conociendo los valores
>> de
>> las columnas de periodos.
>> Lo que me gustaría hacer es la misma consulta pero pudiendo cambiar los
>> periodos de forma dinámica, sin escribirlos en la sentencia PIVOT.
>>
>> Si alguien se le ocurre como...
>
>



Respuesta Responder a este mensaje
#4 Javier Loria
24/10/2006 - 15:35 | Informe spam
Hola:
Por mucho programar la consulta en la capa de presentacion seria mucho
mejor.
Saludos,


Javier Loria
Costa Rica-MVP
Solid Quality Learning

"Paco" wrote in message
news:
Muchas Gracias a los dos. Deduzco por vuestras respuestas que mis únicas
opciones para hacerlo son sql dinámico o programarlo en la capa de
presentación.


"Maxi" wrote:

Exacto, una de las razones de porque esto funciona es asi es porque el
pivot
de sql2005 es ANSI


Saludos

[Microsoft MVP SQL Server]
www.sqlgurus.org
Buenos Aires - Argentina
"Javier Loria" wrote in message
news:
> Hola:
> No existe forma de hacer esto, sin usar SQL Dinamico. Puedes revisar
> http://www.hayes.ch/sql/sql_dinamico.html.
> En todo caso si lo necesitas seria un codigo horrible, algo como:
> =>> > DECLARE @Columna NVARCHAR(MAX);
> DECLARE @Sentencia NVARCHAR(MAX);
> SET @SeNtencia='SELECT *
> from
> (
> SELECT Periodos.Periodo
> , Movimientos.Articulo
> , Movimientos.Importe
> FROM dbo.ListaPeriodos(''SEMANA'', ' +
> CONVERT(VARCHAR(8), @FDesde, 112) + ', '
> +CONVERT(VARCHAR(8), @FHasta, 112)+ ')
> AS Periodos
> INNER JOIN Movimientos
> ON Movimientos.Fecha >= Periodos.FechaDesde
> AND Movimientos.Fecha <= Periodos.FechaHasta) p
> PIVOT(SUM(Importe) for titulo in (';
>
> WITH Fechas(Fecha)
> AS
> ( SELECT CAST(@FDesde AS SMALLDATETIME)
> UNION ALL
> SELECT DATEADD(DAY, 1, Fecha)
> FROM Fechas
> WHERE Fecha<@FHasta
> )
> SELECT @Columna=COALESCE(@Columna+ ', ['+
> CONVERT(VARCHAR(8), Fecha, 112)+']','['+CONVERT(VARCHAR(8), Fecha,
> 112)+']')
> FROM Fechas;
> SET @Sentencia=@Sentencia+@Columna+')) as pvt';
>
> execute sp_executesql @Sentencia
> ==>> > Saludos,
>
>
> Javier Loria
> Costa Rica-MVP
> Solid Quality Learning
>
> "Paco" wrote in message
> news:
>> Hola
>>
>> Necesito hacer una consulta con PIVOT creando las columnas de forma
>> dinámica.
>> Os explico un poco lo que he hecho para que podais entender mejor el
>> objetivo.
>>
>> Tengo una tabla de movimientos de este tipo:
>>
>> Fecha (k)
>> Producto (k)
>> Importe
>>
>> Tengo otra tabla con los periodos a consultar :
>>
>> Periodo (k)
>> FechaDesde
>> FechaHasta
>>
>> Esta tabla se devuelve de una función y el tipo de periodo puede ser
>> dias,semanas,mes,año,decena,quincena,trimestre, etc...
>>
>> Para hacer pivot he probado con este ejemplo:
>>
>> SELECT Articulo, [15/2006], [16/2006] from
>> (
>> SELECT Periodos.Periodo, Movimientos.Articulo, Movimientos.Importe
>> FROM dbo.ListaPeriodos('SEMANA', @FDesde, @FHasta) AS Periodos
>> INNER JOIN
>> Movimientos ON Movimientos.Fecha >>> >> Periodos.FechaDesde AND
>> Movimientos.Fecha <= Periodos.FechaHasta
>> ) p
>> pivot
>> (
>> sum(Importe) for titulo in ([15/2006],[16/2006]))
>> as pvt
>>
>> Con esto consigo el siguiente resultado :
>>
>> Articulo [15/2006] [16/2006]
>> 1 125 250
>> 2 135 365
>> 3 0 52
>> 4 50 26
>>
>> He conseguido acercarme al objetivo pero siempre conociendo los
>> valores
>> de
>> las columnas de periodos.
>> Lo que me gustaría hacer es la misma consulta pero pudiendo cambiar
>> los
>> periodos de forma dinámica, sin escribirlos en la sentencia PIVOT.
>>
>> Si alguien se le ocurre como...
>
>



Respuesta Responder a este mensaje
#5 Agustin
30/10/2006 - 13:01 | Informe spam
A mi me a funconado con un codigo como este me crea otra tabla pivoteada por
los campos que yo quiero

/*dbo.SimpleXTab3 'observacion','Viewlote','','max','valor','idlote'*/

CREATE PROCEDURE [dbo].[SimpleXTab3]
AS
Declare @XField varChar(20)
Declare @XTable varChar(20)
Declare @XWhereString varChar(400)
Declare @XFunction varChar(10)
Declare @XFunctionField varChar(40)
Declare @XRow varchar(40)

Declare @SqlStr nvarchar(4000)
Declare @tempsql nvarchar(4000)
Declare @SqlStrCur nvarchar(4000)
Declare @col nvarchar(400)

set @XField ="Observacion"
set @XTable ="ViewLote"
set @XWhereString=""
set @XFunction ="Max"
set @XFunctionField ="Valor"
set @XRow ="IdTipoLote,IdLote"

drop table CrossMatricula

set @SqlStrCur = N'Select [' + @XField + '] into ##temptbl_Cursor from [' +
@XTable + '] ' + @XWhereString + ' Group By [' + @XField + ']'

/* select @sqlstrcur */
exec sp_executesql @sqlstrcur



declare xcursor Cursor for Select * from ##temptbl_Cursor

open xcursor


Fetch next from xcursor
into @Col


While @@Fetch_Status = 0
Begin
set @Sqlstr = @Sqlstr + ", "
set @tempsql = isnull(@sqlstr,'') + isnull(@XFunction + '( Case When ' +
@XField + " = '" +@Col +
"' then [" + @XFunctionField + "] Else '' End)
As [" + @Col + "]" ,'')
set @Sqlstr = @tempsql
Fetch next from xcursor into @Col

End


/* Select @Sqlstr as [mk], len(@sqlstr) as [leng] */

set @tempsql = 'Select ' + @XRow + ', ' + @Sqlstr + ' INTO CrossMatricula
From ' + @XTable +
@XWhereString + ' Group by ' + @XRow
set @Sqlstr = @tempsql


Close xcursor
Deallocate xcursor

set @tempsql = N'Drop Table ##temptbl_Cursor'


/*select * INTO cursorWW from @sqlstrcur*/
exec sp_executesql @tempsql

/* Select @Sqlstr as [mk], len(@sqlstr) as [leng] */

exec sp_executesql @Sqlstr



GO


Agustin Restrepo
Ingeniero de Sistemas
Centro de Atencion En Sistemas Ltda
Celular 310-4418437
Beeper 2659777 Cod 47192
Email:
"Paco" escribió en el mensaje
news:
Hola

Necesito hacer una consulta con PIVOT creando las columnas de forma


dinámica.
Os explico un poco lo que he hecho para que podais entender mejor el


objetivo.

Tengo una tabla de movimientos de este tipo:

Fecha (k)
Producto (k)
Importe

Tengo otra tabla con los periodos a consultar :

Periodo (k)
FechaDesde
FechaHasta

Esta tabla se devuelve de una función y el tipo de periodo puede ser
dias,semanas,mes,año,decena,quincena,trimestre, etc...

Para hacer pivot he probado con este ejemplo:

SELECT Articulo, [15/2006], [16/2006] from
(
SELECT Periodos.Periodo, Movimientos.Articulo, Movimientos.Importe
FROM dbo.ListaPeriodos('SEMANA', @FDesde, @FHasta) AS Periodos
INNER JOIN
Movimientos ON Movimientos.Fecha >> Periodos.FechaDesde AND
Movimientos.Fecha <= Periodos.FechaHasta
) p
pivot
(
sum(Importe) for titulo in ([15/2006],[16/2006]))
as pvt

Con esto consigo el siguiente resultado :

Articulo [15/2006] [16/2006]
1 125 250
2 135 365
3 0 52
4 50 26

He conseguido acercarme al objetivo pero siempre conociendo los valores de
las columnas de periodos.
Lo que me gustaría hacer es la misma consulta pero pudiendo cambiar los
periodos de forma dinámica, sin escribirlos en la sentencia PIVOT.

Si alguien se le ocurre como...
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida