Pivotar en SQL 2000.

15/05/2007 - 18:08 por Salvador Ramos | Informe spam
Hola a todos,

Tengo una tabla con la siguiente estructura: Proveedor, RefProv, EAN,
Descripcion, Precio, PrecioNeto
En ella importo datos de las tarifas de diferentes proveedores. Tengo entre
1000 y 2000 filas por proveedor, y artículos cuyo código EAN coincide entre
diversos proveedores (a priori no sé cuantos). La PK de esta tabla es
Proveedor+RefProv

Lo que necesito es hacer una consulta que me devuelva: EAN, Descripcion,
"PrecioNeto de cada proveedor".
Por tanto necesito las dos primeras columnas más una por cada PrecioNeto, en
función de cuantos proveedores tengan ese código EAN. La verdad que no se me
ocurre como obtener ese número de columnas variable, y además tengo que
hacerlo para SQL Server 2000.

Pd. También me interesaría ver la solución con 2005 para compararla (pero
vamos esto es opcional).
Pd2. Siempre me queda la alternativa de montar un cubo muy sencillo sobre
esa tabla, pero me gustaría optar por una solución en el relacional :-)

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm

Preguntas similare

Leer las respuestas

#1 Liliana Sorrentino
15/05/2007 - 20:45 | Informe spam
Hola Salvador,
Te paso una forma de resolverlo con SQL 2000, usando un SP que genera una
cantidad dinámica de columnas, no es mío, es de esas cosas que uno copia y
pega desde el foro.
No puedo decirte si es bueno el rendimiento porque las veces que lo necesité
fue para usarlo con menos de 10 millones de filas.
Espero que te sirva,
Liliana.

DROP Procedure #Proc_Query_Pivot_1
GO
CREATE Procedure #proc_Query_Pivot_1
@Datos_Base_SQL varchar(2000), -- SQL que devuelve datos para la
construcción de la tabla cruzada
@Encabe_Fila varchar(200), -- Lista de filas para usar como dato de
agrupamiento
@Encabe_Columna varchar(200), -- Nombre del dato que se usará como
encabezado de columna
@Titulo_Columna_SQL varchar(2000), -- SQL que devuelve los posibles
encabezados
@Operacion varchar(10), -- SUM, PRODUCT, etc
@Argumento varchar(200), -- Columna argumento de la operacion
@Totales char(1) -- 'S' incluye totales generales, 'N' los omite

AS

Declare @SQL varchar(2000),
@Summary_SQL varchar(2000) -- to summarize each row

Set @SQL = 'SELECT ' + @Encabe_Fila + ', '
Set @Summary_SQL = ''

CREATE TABLE #Col_Encabes
(Col_ID int identity(1,1),
Col_Encabe varchar(200) NULL)

Exec ('INSERT INTO #Col_Encabes (Col_Encabe) ' + @Titulo_Columna_SQL)

DECLARE @Col_ID_Curr int, -- columna chequeada
@Col_ID_Old int,
@Curr_Col_Encabe varchar(200),
@Pivot_SQL varchar(200) -- pivot SQL para la columna

SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes ORDER BY Col_ID

IF (@Col_ID_Curr IS NOT NULL )
BEGIN
Set @Col_ID_Old = @Col_ID_Curr - 1

WHILE (@Col_ID_Old <> @Col_ID_Curr)
BEGIN
Set @Pivot_SQL = char(13) + @Operacion
+ '(CASE ' + @Encabe_Columna
+ ' WHEN ''' + @Curr_Col_Encabe + ''' THEN ' + @Argumento
+ ' ELSE SPACE(2) END) AS [' + @Curr_Col_Encabe + ']'
Set @SQL = @SQL + ' ' + @Pivot_SQL

If (@Totales='S')
Set @Summary_SQL = @Summary_SQL + 'Pivot_Data.[' + @Curr_Col_Encabe + ']'

Set @Col_ID_Old = @Col_ID_Curr
SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes
WHERE Col_ID > @Col_ID_Curr
ORDER BY Col_ID

IF (@Col_ID_Old <> @Col_ID_Curr)
Begin
Set @SQL = @SQL + ', '
Set @Summary_SQL = @Summary_SQL + ' + '
End
END
END



DROP TABLE #Col_Encabes

Set @SQL = @SQL + char(13) + 'FROM (' + @Datos_Base_SQL + ') AS Datos_Base
'
+ char(13) + 'GROUP BY ' + @Encabe_Fila

If (@Totales='S')
Set @SQL = 'SELECT Pivot_Data.*, ' + char(13)
+ ' (' + @Summary_SQL + ') AS TOTAL ' + char(13)
+ 'FROM (' + @SQL + ') AS Pivot_Data'


Print @SQL
Select ''
Exec (@SQL)
go


EXEC #proc_Query_Pivot_1
micondicion"
'SELECT Proveedor, EAN, Descripcion, Precio
FROM #Prov',
'EAN',
'Proveedor',
'SELECT DISTINCT Proveedor FROM #Prov',
'MAX',
'Precio',
'n'




"Salvador Ramos" escribió en el
mensaje news:
Hola a todos,

Tengo una tabla con la siguiente estructura: Proveedor, RefProv, EAN,
Descripcion, Precio, PrecioNeto
En ella importo datos de las tarifas de diferentes proveedores. Tengo
entre 1000 y 2000 filas por proveedor, y artículos cuyo código EAN
coincide entre diversos proveedores (a priori no sé cuantos). La PK de
esta tabla es Proveedor+RefProv

Lo que necesito es hacer una consulta que me devuelva: EAN, Descripcion,
"PrecioNeto de cada proveedor".
Por tanto necesito las dos primeras columnas más una por cada PrecioNeto,
en función de cuantos proveedores tengan ese código EAN. La verdad que no
se me ocurre como obtener ese número de columnas variable, y además tengo
que hacerlo para SQL Server 2000.

Pd. También me interesaría ver la solución con 2005 para compararla (pero
vamos esto es opcional).
Pd2. Siempre me queda la alternativa de montar un cubo muy sencillo sobre
esa tabla, pero me gustaría optar por una solución en el relacional :-)

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm



Respuesta Responder a este mensaje
#2 Salvador Ramos
16/05/2007 - 10:22 | Informe spam
Muchas gracias Liliana,

Resuelve perfectamente el problema planteado, y no me preocupa el
rendimiento, ya que la tabla origen de los datos no superará las 10.000
filas.

Ahora lo que me preocupa es que el usuario empezará a pedirme variantes
sobre estos resultados, querrá hacer join con la tabla de Articulos por la
columna CodBarras para obtener columas de dicha tabla, obtener el precio más
bajo entre todas las columnas y demás. Así que voy a hablar con él, y si es
como intuyo, basandome en lo que me has enviado voy a crear una nueva tabla
que se actualice periódicamente y así poder utilizarla con mayor
flexibilidad.
Para ello en las prueba he modificado la siguiente línea añadiendo INTO #T1
Set @SQL = @SQL + char(13) + ' INTO #T1 FROM (' + @Datos_Base_SQL + ') AS
Datos_Base

Creo que voy a optar por hacerlo así, ya que es una tabla que se actualiza
con muy poca frecuencia y se consulta mucho.

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm


"Liliana Sorrentino" escribió en el mensaje
news:
Hola Salvador,
Te paso una forma de resolverlo con SQL 2000, usando un SP que genera una
cantidad dinámica de columnas, no es mío, es de esas cosas que uno copia y
pega desde el foro.
No puedo decirte si es bueno el rendimiento porque las veces que lo
necesité fue para usarlo con menos de 10 millones de filas.
Espero que te sirva,
Liliana.

DROP Procedure #Proc_Query_Pivot_1
GO
CREATE Procedure #proc_Query_Pivot_1
@Datos_Base_SQL varchar(2000), -- SQL que devuelve datos para la
construcción de la tabla cruzada
@Encabe_Fila varchar(200), -- Lista de filas para usar como dato de
agrupamiento
@Encabe_Columna varchar(200), -- Nombre del dato que se usará como
encabezado de columna
@Titulo_Columna_SQL varchar(2000), -- SQL que devuelve los posibles
encabezados
@Operacion varchar(10), -- SUM, PRODUCT, etc
@Argumento varchar(200), -- Columna argumento de la operacion
@Totales char(1) -- 'S' incluye totales generales, 'N' los omite

AS

Declare @SQL varchar(2000),
@Summary_SQL varchar(2000) -- to summarize each row

Set @SQL = 'SELECT ' + @Encabe_Fila + ', '
Set @Summary_SQL = ''

CREATE TABLE #Col_Encabes
(Col_ID int identity(1,1),
Col_Encabe varchar(200) NULL)

Exec ('INSERT INTO #Col_Encabes (Col_Encabe) ' + @Titulo_Columna_SQL)

DECLARE @Col_ID_Curr int, -- columna chequeada
@Col_ID_Old int,
@Curr_Col_Encabe varchar(200),
@Pivot_SQL varchar(200) -- pivot SQL para la columna

SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes ORDER BY Col_ID

IF (@Col_ID_Curr IS NOT NULL )
BEGIN
Set @Col_ID_Old = @Col_ID_Curr - 1

WHILE (@Col_ID_Old <> @Col_ID_Curr)
BEGIN
Set @Pivot_SQL = char(13) + @Operacion
+ '(CASE ' + @Encabe_Columna
+ ' WHEN ''' + @Curr_Col_Encabe + ''' THEN ' + @Argumento
+ ' ELSE SPACE(2) END) AS [' + @Curr_Col_Encabe + ']'
Set @SQL = @SQL + ' ' + @Pivot_SQL

If (@Totales='S')
Set @Summary_SQL = @Summary_SQL + 'Pivot_Data.[' + @Curr_Col_Encabe +
']'

Set @Col_ID_Old = @Col_ID_Curr
SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes
WHERE Col_ID > @Col_ID_Curr
ORDER BY Col_ID

IF (@Col_ID_Old <> @Col_ID_Curr)
Begin
Set @SQL = @SQL + ', '
Set @Summary_SQL = @Summary_SQL + ' + '
End
END
END



DROP TABLE #Col_Encabes

Set @SQL = @SQL + char(13) + 'FROM (' + @Datos_Base_SQL + ') AS
Datos_Base '
+ char(13) + 'GROUP BY ' + @Encabe_Fila

If (@Totales='S')
Set @SQL = 'SELECT Pivot_Data.*, ' + char(13)
+ ' (' + @Summary_SQL + ') AS TOTAL ' + char(13)
+ 'FROM (' + @SQL + ') AS Pivot_Data'


Print @SQL
Select ''
Exec (@SQL)
go


EXEC #proc_Query_Pivot_1
micondicion"
'SELECT Proveedor, EAN, Descripcion, Precio
FROM #Prov',
'EAN',
'Proveedor',
'SELECT DISTINCT Proveedor FROM #Prov',
'MAX',
'Precio',
'n'




"Salvador Ramos" escribió en el
mensaje news:
Hola a todos,

Tengo una tabla con la siguiente estructura: Proveedor, RefProv, EAN,
Descripcion, Precio, PrecioNeto
En ella importo datos de las tarifas de diferentes proveedores. Tengo
entre 1000 y 2000 filas por proveedor, y artículos cuyo código EAN
coincide entre diversos proveedores (a priori no sé cuantos). La PK de
esta tabla es Proveedor+RefProv

Lo que necesito es hacer una consulta que me devuelva: EAN, Descripcion,
"PrecioNeto de cada proveedor".
Por tanto necesito las dos primeras columnas más una por cada PrecioNeto,
en función de cuantos proveedores tengan ese código EAN. La verdad que no
se me ocurre como obtener ese número de columnas variable, y además tengo
que hacerlo para SQL Server 2000.

Pd. También me interesaría ver la solución con 2005 para compararla (pero
vamos esto es opcional).
Pd2. Siempre me queda la alternativa de montar un cubo muy sencillo sobre
esa tabla, pero me gustaría optar por una solución en el relacional :-)

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm







Respuesta Responder a este mensaje
#3 Salvador Ramos
16/05/2007 - 11:16 | Informe spam
Habría alguna solución sin usar sql dinámico en 2005 ?

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm


"Liliana Sorrentino" escribió en el mensaje
news:
Hola Salvador,
Te paso una forma de resolverlo con SQL 2000, usando un SP que genera una
cantidad dinámica de columnas, no es mío, es de esas cosas que uno copia y
pega desde el foro.
No puedo decirte si es bueno el rendimiento porque las veces que lo
necesité fue para usarlo con menos de 10 millones de filas.
Espero que te sirva,
Liliana.

DROP Procedure #Proc_Query_Pivot_1
GO
CREATE Procedure #proc_Query_Pivot_1
@Datos_Base_SQL varchar(2000), -- SQL que devuelve datos para la
construcción de la tabla cruzada
@Encabe_Fila varchar(200), -- Lista de filas para usar como dato de
agrupamiento
@Encabe_Columna varchar(200), -- Nombre del dato que se usará como
encabezado de columna
@Titulo_Columna_SQL varchar(2000), -- SQL que devuelve los posibles
encabezados
@Operacion varchar(10), -- SUM, PRODUCT, etc
@Argumento varchar(200), -- Columna argumento de la operacion
@Totales char(1) -- 'S' incluye totales generales, 'N' los omite

AS

Declare @SQL varchar(2000),
@Summary_SQL varchar(2000) -- to summarize each row

Set @SQL = 'SELECT ' + @Encabe_Fila + ', '
Set @Summary_SQL = ''

CREATE TABLE #Col_Encabes
(Col_ID int identity(1,1),
Col_Encabe varchar(200) NULL)

Exec ('INSERT INTO #Col_Encabes (Col_Encabe) ' + @Titulo_Columna_SQL)

DECLARE @Col_ID_Curr int, -- columna chequeada
@Col_ID_Old int,
@Curr_Col_Encabe varchar(200),
@Pivot_SQL varchar(200) -- pivot SQL para la columna

SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes ORDER BY Col_ID

IF (@Col_ID_Curr IS NOT NULL )
BEGIN
Set @Col_ID_Old = @Col_ID_Curr - 1

WHILE (@Col_ID_Old <> @Col_ID_Curr)
BEGIN
Set @Pivot_SQL = char(13) + @Operacion
+ '(CASE ' + @Encabe_Columna
+ ' WHEN ''' + @Curr_Col_Encabe + ''' THEN ' + @Argumento
+ ' ELSE SPACE(2) END) AS [' + @Curr_Col_Encabe + ']'
Set @SQL = @SQL + ' ' + @Pivot_SQL

If (@Totales='S')
Set @Summary_SQL = @Summary_SQL + 'Pivot_Data.[' + @Curr_Col_Encabe +
']'

Set @Col_ID_Old = @Col_ID_Curr
SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes
WHERE Col_ID > @Col_ID_Curr
ORDER BY Col_ID

IF (@Col_ID_Old <> @Col_ID_Curr)
Begin
Set @SQL = @SQL + ', '
Set @Summary_SQL = @Summary_SQL + ' + '
End
END
END



DROP TABLE #Col_Encabes

Set @SQL = @SQL + char(13) + 'FROM (' + @Datos_Base_SQL + ') AS
Datos_Base '
+ char(13) + 'GROUP BY ' + @Encabe_Fila

If (@Totales='S')
Set @SQL = 'SELECT Pivot_Data.*, ' + char(13)
+ ' (' + @Summary_SQL + ') AS TOTAL ' + char(13)
+ 'FROM (' + @SQL + ') AS Pivot_Data'


Print @SQL
Select ''
Exec (@SQL)
go


EXEC #proc_Query_Pivot_1
micondicion"
'SELECT Proveedor, EAN, Descripcion, Precio
FROM #Prov',
'EAN',
'Proveedor',
'SELECT DISTINCT Proveedor FROM #Prov',
'MAX',
'Precio',
'n'




"Salvador Ramos" escribió en el
mensaje news:
Hola a todos,

Tengo una tabla con la siguiente estructura: Proveedor, RefProv, EAN,
Descripcion, Precio, PrecioNeto
En ella importo datos de las tarifas de diferentes proveedores. Tengo
entre 1000 y 2000 filas por proveedor, y artículos cuyo código EAN
coincide entre diversos proveedores (a priori no sé cuantos). La PK de
esta tabla es Proveedor+RefProv

Lo que necesito es hacer una consulta que me devuelva: EAN, Descripcion,
"PrecioNeto de cada proveedor".
Por tanto necesito las dos primeras columnas más una por cada PrecioNeto,
en función de cuantos proveedores tengan ese código EAN. La verdad que no
se me ocurre como obtener ese número de columnas variable, y además tengo
que hacerlo para SQL Server 2000.

Pd. También me interesaría ver la solución con 2005 para compararla (pero
vamos esto es opcional).
Pd2. Siempre me queda la alternativa de montar un cubo muy sencillo sobre
esa tabla, pero me gustaría optar por una solución en el relacional :-)

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm







Respuesta Responder a este mensaje
#4 Javier Loria
16/05/2007 - 15:49 | Informe spam
Hola Salvador:
Puedes usar el comando PIVOT, pero este no es dinamico es fijo, de
manera que siempre tendar que hacer SQL Dinamico, pero mucho mucho mas
sencillo. Un ejemplo de como hacer un PIVOT con AdventureWorks;
=SELECT *
FROM (SELECT
SalesPersonID
, SubTotal
, YEAR(OrderDate) AS Year
FROM Sales.SalesOrderHeader
) AS Base
PIVOT
(
SUM(SubTotal)
FOR [Year] IN ([2002], [2003], [2004])
) AS pvt;
= En el caso que quisieras los años dinamicos hay que construir el comando
con SQL Dinamico para generar la lista de las columnas con un SELECT
DISTINCT de los años.
Claro que la solucion, como bien lo dijiste es, . UN CUBO!!!! ;-)
Saludos y a ver si nos vemos durante en el Summit.

Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Salvador Ramos" wrote in message
news:%
Habría alguna solución sin usar sql dinámico en 2005 ?

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm


"Liliana Sorrentino" escribió en el
mensaje news:
Hola Salvador,
Te paso una forma de resolverlo con SQL 2000, usando un SP que genera una
cantidad dinámica de columnas, no es mío, es de esas cosas que uno copia
y pega desde el foro.
No puedo decirte si es bueno el rendimiento porque las veces que lo
necesité fue para usarlo con menos de 10 millones de filas.
Espero que te sirva,
Liliana.

DROP Procedure #Proc_Query_Pivot_1
GO
CREATE Procedure #proc_Query_Pivot_1
@Datos_Base_SQL varchar(2000), -- SQL que devuelve datos para la
construcción de la tabla cruzada
@Encabe_Fila varchar(200), -- Lista de filas para usar como dato de
agrupamiento
@Encabe_Columna varchar(200), -- Nombre del dato que se usará como
encabezado de columna
@Titulo_Columna_SQL varchar(2000), -- SQL que devuelve los posibles
encabezados
@Operacion varchar(10), -- SUM, PRODUCT, etc
@Argumento varchar(200), -- Columna argumento de la operacion
@Totales char(1) -- 'S' incluye totales generales, 'N' los omite

AS

Declare @SQL varchar(2000),
@Summary_SQL varchar(2000) -- to summarize each row

Set @SQL = 'SELECT ' + @Encabe_Fila + ', '
Set @Summary_SQL = ''

CREATE TABLE #Col_Encabes
(Col_ID int identity(1,1),
Col_Encabe varchar(200) NULL)

Exec ('INSERT INTO #Col_Encabes (Col_Encabe) ' + @Titulo_Columna_SQL)

DECLARE @Col_ID_Curr int, -- columna chequeada
@Col_ID_Old int,
@Curr_Col_Encabe varchar(200),
@Pivot_SQL varchar(200) -- pivot SQL para la columna

SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes ORDER BY Col_ID

IF (@Col_ID_Curr IS NOT NULL )
BEGIN
Set @Col_ID_Old = @Col_ID_Curr - 1

WHILE (@Col_ID_Old <> @Col_ID_Curr)
BEGIN
Set @Pivot_SQL = char(13) + @Operacion
+ '(CASE ' + @Encabe_Columna
+ ' WHEN ''' + @Curr_Col_Encabe + ''' THEN ' + @Argumento
+ ' ELSE SPACE(2) END) AS [' + @Curr_Col_Encabe + ']'
Set @SQL = @SQL + ' ' + @Pivot_SQL

If (@Totales='S')
Set @Summary_SQL = @Summary_SQL + 'Pivot_Data.[' + @Curr_Col_Encabe +
']'

Set @Col_ID_Old = @Col_ID_Curr
SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes
WHERE Col_ID > @Col_ID_Curr
ORDER BY Col_ID

IF (@Col_ID_Old <> @Col_ID_Curr)
Begin
Set @SQL = @SQL + ', '
Set @Summary_SQL = @Summary_SQL + ' + '
End
END
END



DROP TABLE #Col_Encabes

Set @SQL = @SQL + char(13) + 'FROM (' + @Datos_Base_SQL + ') AS
Datos_Base '
+ char(13) + 'GROUP BY ' + @Encabe_Fila

If (@Totales='S')
Set @SQL = 'SELECT Pivot_Data.*, ' + char(13)
+ ' (' + @Summary_SQL + ') AS TOTAL ' + char(13)
+ 'FROM (' + @SQL + ') AS Pivot_Data'


Print @SQL
Select ''
Exec (@SQL)
go


EXEC #proc_Query_Pivot_1
micondicion"
'SELECT Proveedor, EAN, Descripcion, Precio
FROM #Prov',
'EAN',
'Proveedor',
'SELECT DISTINCT Proveedor FROM #Prov',
'MAX',
'Precio',
'n'




"Salvador Ramos" escribió en el
mensaje news:
Hola a todos,

Tengo una tabla con la siguiente estructura: Proveedor, RefProv, EAN,
Descripcion, Precio, PrecioNeto
En ella importo datos de las tarifas de diferentes proveedores. Tengo
entre 1000 y 2000 filas por proveedor, y artículos cuyo código EAN
coincide entre diversos proveedores (a priori no sé cuantos). La PK de
esta tabla es Proveedor+RefProv

Lo que necesito es hacer una consulta que me devuelva: EAN, Descripcion,
"PrecioNeto de cada proveedor".
Por tanto necesito las dos primeras columnas más una por cada
PrecioNeto, en función de cuantos proveedores tengan ese código EAN. La
verdad que no se me ocurre como obtener ese número de columnas variable,
y además tengo que hacerlo para SQL Server 2000.

Pd. También me interesaría ver la solución con 2005 para compararla
(pero vamos esto es opcional).
Pd2. Siempre me queda la alternativa de montar un cubo muy sencillo
sobre esa tabla, pero me gustaría optar por una solución en el
relacional :-)

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm











Respuesta Responder a este mensaje
#5 Salvador Ramos
16/05/2007 - 16:10 | Informe spam
Muchas gracias Javier,

Más que nada era por confirmar que no se me había pasado alguna forma de
evitar el sql dinámico.
Efectivamente, voy a buscar una solución a corto plazo basada en el
relacional sobre 2000. Y me voy a plantear un cubo más tranquilamente, que
ofrezca toda la información necesaria de una forma más flexible.

Claro que si, nos vemos en el Summit, que ya está cerquita :-)

Pd. Si queréis saber a qué Summit nos referimos Javier y yo, aquí tenéis un
link
http://learning.solidq.com/ib/Cours...ScheduleId!5

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm


"Javier Loria" escribió en el mensaje
news:
Hola Salvador:
Puedes usar el comando PIVOT, pero este no es dinamico es fijo, de
manera que siempre tendar que hacer SQL Dinamico, pero mucho mucho mas
sencillo. Un ejemplo de como hacer un PIVOT con AdventureWorks;
=> SELECT *
FROM (SELECT
SalesPersonID
, SubTotal
, YEAR(OrderDate) AS Year
FROM Sales.SalesOrderHeader
) AS Base
PIVOT
(
SUM(SubTotal)
FOR [Year] IN ([2002], [2003], [2004])
) AS pvt;
=> En el caso que quisieras los años dinamicos hay que construir el
comando con SQL Dinamico para generar la lista de las columnas con un
SELECT DISTINCT de los años.
Claro que la solucion, como bien lo dijiste es, . UN CUBO!!!! ;-)
Saludos y a ver si nos vemos durante en el Summit.

Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Salvador Ramos" wrote in message
news:%
Habría alguna solución sin usar sql dinámico en 2005 ?

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm


"Liliana Sorrentino" escribió en el
mensaje news:
Hola Salvador,
Te paso una forma de resolverlo con SQL 2000, usando un SP que genera
una cantidad dinámica de columnas, no es mío, es de esas cosas que uno
copia y pega desde el foro.
No puedo decirte si es bueno el rendimiento porque las veces que lo
necesité fue para usarlo con menos de 10 millones de filas.
Espero que te sirva,
Liliana.

DROP Procedure #Proc_Query_Pivot_1
GO
CREATE Procedure #proc_Query_Pivot_1
@Datos_Base_SQL varchar(2000), -- SQL que devuelve datos para la
construcción de la tabla cruzada
@Encabe_Fila varchar(200), -- Lista de filas para usar como dato de
agrupamiento
@Encabe_Columna varchar(200), -- Nombre del dato que se usará como
encabezado de columna
@Titulo_Columna_SQL varchar(2000), -- SQL que devuelve los posibles
encabezados
@Operacion varchar(10), -- SUM, PRODUCT, etc
@Argumento varchar(200), -- Columna argumento de la operacion
@Totales char(1) -- 'S' incluye totales generales, 'N' los omite

AS

Declare @SQL varchar(2000),
@Summary_SQL varchar(2000) -- to summarize each row

Set @SQL = 'SELECT ' + @Encabe_Fila + ', '
Set @Summary_SQL = ''

CREATE TABLE #Col_Encabes
(Col_ID int identity(1,1),
Col_Encabe varchar(200) NULL)

Exec ('INSERT INTO #Col_Encabes (Col_Encabe) ' + @Titulo_Columna_SQL)

DECLARE @Col_ID_Curr int, -- columna chequeada
@Col_ID_Old int,
@Curr_Col_Encabe varchar(200),
@Pivot_SQL varchar(200) -- pivot SQL para la columna

SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes ORDER BY Col_ID

IF (@Col_ID_Curr IS NOT NULL )
BEGIN
Set @Col_ID_Old = @Col_ID_Curr - 1

WHILE (@Col_ID_Old <> @Col_ID_Curr)
BEGIN
Set @Pivot_SQL = char(13) + @Operacion
+ '(CASE ' + @Encabe_Columna
+ ' WHEN ''' + @Curr_Col_Encabe + ''' THEN ' + @Argumento
+ ' ELSE SPACE(2) END) AS [' + @Curr_Col_Encabe + ']'
Set @SQL = @SQL + ' ' + @Pivot_SQL

If (@Totales='S')
Set @Summary_SQL = @Summary_SQL + 'Pivot_Data.[' + @Curr_Col_Encabe +
']'

Set @Col_ID_Old = @Col_ID_Curr
SELECT TOP 1 @Col_ID_Curr = Col_ID, @Curr_Col_Encabe = Col_Encabe
FROM #Col_Encabes
WHERE Col_ID > @Col_ID_Curr
ORDER BY Col_ID

IF (@Col_ID_Old <> @Col_ID_Curr)
Begin
Set @SQL = @SQL + ', '
Set @Summary_SQL = @Summary_SQL + ' + '
End
END
END



DROP TABLE #Col_Encabes

Set @SQL = @SQL + char(13) + 'FROM (' + @Datos_Base_SQL + ') AS
Datos_Base '
+ char(13) + 'GROUP BY ' + @Encabe_Fila

If (@Totales='S')
Set @SQL = 'SELECT Pivot_Data.*, ' + char(13)
+ ' (' + @Summary_SQL + ') AS TOTAL ' + char(13)
+ 'FROM (' + @SQL + ') AS Pivot_Data'


Print @SQL
Select ''
Exec (@SQL)
go


EXEC #proc_Query_Pivot_1
micondicion"
'SELECT Proveedor, EAN, Descripcion, Precio
FROM #Prov',
'EAN',
'Proveedor',
'SELECT DISTINCT Proveedor FROM #Prov',
'MAX',
'Precio',
'n'




"Salvador Ramos" escribió en el
mensaje news:
Hola a todos,

Tengo una tabla con la siguiente estructura: Proveedor, RefProv, EAN,
Descripcion, Precio, PrecioNeto
En ella importo datos de las tarifas de diferentes proveedores. Tengo
entre 1000 y 2000 filas por proveedor, y artículos cuyo código EAN
coincide entre diversos proveedores (a priori no sé cuantos). La PK de
esta tabla es Proveedor+RefProv

Lo que necesito es hacer una consulta que me devuelva: EAN,
Descripcion, "PrecioNeto de cada proveedor".
Por tanto necesito las dos primeras columnas más una por cada
PrecioNeto, en función de cuantos proveedores tengan ese código EAN. La
verdad que no se me ocurre como obtener ese número de columnas
variable, y además tengo que hacerlo para SQL Server 2000.

Pd. También me interesaría ver la solución con 2005 para compararla
(pero vamos esto es opcional).
Pd2. Siempre me queda la alternativa de montar un cubo muy sencillo
sobre esa tabla, pero me gustaría optar por una solución en el
relacional :-)

Un saludo
Salvador Ramos

www.helpdna.net (información sobre SQL Server y Microsoft .Net)
www.helpdna.net/acerca_de_salvador_ramos.htm














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