Pivot -- script

08/07/2007 - 00:46 por Pedro | Informe spam
Hola

Estoy con un script.
Esplico que quiero hacer, resumiendo:

Tengo 2 tablas:

Tabla1 :
CampoCodigoPieza CampoDescripcionPieza
ABV3456 Pantalones Azules
AVBG567 Pantalones Grines
AGH5678 Pantalones Verdes
...


Tabla2 :
CampoNombreCiente CampoPiezaComprada
Jorge ABV3456
Carlos AGH5678
Jorge ABV3456
Pedro ABV3456


Quiero obtener un Script que me genere una tabla3 de la forma:
CampoCiente PantalonAzules PantalonVerdes PantalonGris
Jorge 1 0 1

Carlos 0 1 0

Pedro 1 0 0

Que ponga 1 si comapra ese modelo, 0 si no compara ese mododelo.

He estado mirando de hacerlo mediante el PIVOT pero no me vale de la forma:

Select CampoCodigoPieza as campocliente, [ABV3456] as "PantalonAzules",
[AVBG567] as "PantalonVerdes", [AGH5678] as "PantalonGris"
from tabla1
PIVOT ( for tabla3 in ([ABV3456], [AVBG567], [AGH5678]) as pvt

Pero no me vale ya que me faltaria un campo en la tabla1 del numero de
pantalos que compran de cada tipo. y de este campo habria que hacer un sum()
y ponerlo delante del for

La tabla que me quiero crear mediante un scrip, quiero que si algun dia me
añaden en la tabla1 un nuevo registro la final (tabla3) lo tenga en cuenta y
me aparezca.

Alguna idea.
Gracias

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
08/07/2007 - 02:18 | Informe spam
Hola Pedro,

Trata:

use northwind
go

create table dbo.t1 (
CampoCodigoPieza varchar(15),
CampoDescripcionPieza varchar(50)
)
go

insert into dbo.t1 values('ABV3456', 'Pantalones Azules')
insert into dbo.t1 values('AVBG567', 'Pantalones Grines')
insert into dbo.t1 values('AGH5678', 'Pantalones Verdes')
go

create table dbo.t2 (
CampoNombreCiente varchar(25),
CampoPiezaComprada varchar(15)
)
go

insert into dbo.t2 values('Jorge', 'ABV3456')
insert into dbo.t2 values('Carlos', 'AGH5678')
insert into dbo.t2 values('Jorge', 'AVBG567')
insert into dbo.t2 values('Pedro', 'ABV3456')
go

select
*
from
(
select
b.CampoNombreCiente,
a.CampoDescripcionPieza
from
dbo.t1 as a
inner join
dbo.t2 as b
on a.CampoCodigoPieza = b.CampoPiezaComprada
) as c
pivot
(count(CampoDescripcionPieza) for CampoDescripcionPieza in ([Pantalones
Azules], [Pantalones Verdes], [Pantalones Grines])) as d
go

drop table dbo.t1, dbo.t2
go


AMB


"Pedro" wrote:

Hola

Estoy con un script.
Esplico que quiero hacer, resumiendo:

Tengo 2 tablas:

Tabla1 :
CampoCodigoPieza CampoDescripcionPieza
ABV3456 Pantalones Azules
AVBG567 Pantalones Grines
AGH5678 Pantalones Verdes
...


Tabla2 :
CampoNombreCiente CampoPiezaComprada
Jorge ABV3456
Carlos AGH5678
Jorge ABV3456
Pedro ABV3456


Quiero obtener un Script que me genere una tabla3 de la forma:
CampoCiente PantalonAzules PantalonVerdes PantalonGris
Jorge 1 0 1

Carlos 0 1 0

Pedro 1 0 0

Que ponga 1 si comapra ese modelo, 0 si no compara ese mododelo.

He estado mirando de hacerlo mediante el PIVOT pero no me vale de la forma:

Select CampoCodigoPieza as campocliente, [ABV3456] as "PantalonAzules",
[AVBG567] as "PantalonVerdes", [AGH5678] as "PantalonGris"
from tabla1
PIVOT ( for tabla3 in ([ABV3456], [AVBG567], [AGH5678]) as pvt

Pero no me vale ya que me faltaria un campo en la tabla1 del numero de
pantalos que compran de cada tipo. y de este campo habria que hacer un sum()
y ponerlo delante del for

La tabla que me quiero crear mediante un scrip, quiero que si algun dia me
añaden en la tabla1 un nuevo registro la final (tabla3) lo tenga en cuenta y
me aparezca.

Alguna idea.
Gracias

Respuesta Responder a este mensaje
#2 Pedro
08/07/2007 - 11:22 | Informe spam
Ok, pero se presenta un problema con lo que me pasas:

en la parte del codigo donde pone:
([Pantalones
Azules], [Pantalones Verdes], [Pantalones Grines])
Se ha deconocer y picar en el codigo del script todos los tipos de
pantalones que tenermos, si mañana ponen un nuevo tipo de pantalon hay que
añadirlo amano en el cript.
Hay alguna forma de que tome todod los tipos de pantalon que tenemos en la
Tabla1, y si se añaden nuevos tipos de pantalon, la select con usa el pivot
los tenga enecuenta ya que este escript formara parte de un proceso
diario...

Gracias

"Alejandro Mesa" wrote:

Hola Pedro,

Trata:

use northwind
go

create table dbo.t1 (
CampoCodigoPieza varchar(15),
CampoDescripcionPieza varchar(50)
)
go

insert into dbo.t1 values('ABV3456', 'Pantalones Azules')
insert into dbo.t1 values('AVBG567', 'Pantalones Grines')
insert into dbo.t1 values('AGH5678', 'Pantalones Verdes')
go

create table dbo.t2 (
CampoNombreCiente varchar(25),
CampoPiezaComprada varchar(15)
)
go

insert into dbo.t2 values('Jorge', 'ABV3456')
insert into dbo.t2 values('Carlos', 'AGH5678')
insert into dbo.t2 values('Jorge', 'AVBG567')
insert into dbo.t2 values('Pedro', 'ABV3456')
go

select
*
from
(
select
b.CampoNombreCiente,
a.CampoDescripcionPieza
from
dbo.t1 as a
inner join
dbo.t2 as b
on a.CampoCodigoPieza = b.CampoPiezaComprada
) as c
pivot
(count(CampoDescripcionPieza) for CampoDescripcionPieza in ([Pantalones
Azules], [Pantalones Verdes], [Pantalones Grines])) as d
go

drop table dbo.t1, dbo.t2
go


AMB


"Pedro" wrote:

> Hola
>
> Estoy con un script.
> Esplico que quiero hacer, resumiendo:
>
> Tengo 2 tablas:
>
> Tabla1 :
> CampoCodigoPieza CampoDescripcionPieza
> ABV3456 Pantalones Azules
> AVBG567 Pantalones Grines
> AGH5678 Pantalones Verdes
> ...
>
>
> Tabla2 :
> CampoNombreCiente CampoPiezaComprada
> Jorge ABV3456
> Carlos AGH5678
> Jorge ABV3456
> Pedro ABV3456
>
>
> Quiero obtener un Script que me genere una tabla3 de la forma:
> CampoCiente PantalonAzules PantalonVerdes PantalonGris
> Jorge 1 0 1
>
> Carlos 0 1 0
>
> Pedro 1 0 0
>
> Que ponga 1 si comapra ese modelo, 0 si no compara ese mododelo.
>
> He estado mirando de hacerlo mediante el PIVOT pero no me vale de la forma:
>
> Select CampoCodigoPieza as campocliente, [ABV3456] as "PantalonAzules",
> [AVBG567] as "PantalonVerdes", [AGH5678] as "PantalonGris"
> from tabla1
> PIVOT ( for tabla3 in ([ABV3456], [AVBG567], [AGH5678]) as pvt
>
> Pero no me vale ya que me faltaria un campo en la tabla1 del numero de
> pantalos que compran de cada tipo. y de este campo habria que hacer un sum()
> y ponerlo delante del for
>
> La tabla que me quiero crear mediante un scrip, quiero que si algun dia me
> añaden en la tabla1 un nuevo registro la final (tabla3) lo tenga en cuenta y
> me aparezca.
>
> Alguna idea.
> Gracias
>
Respuesta Responder a este mensaje
#3 Alejandro Mesa
08/07/2007 - 14:58 | Informe spam
Hola Pedro,

Aun no contamos con una forma facil de hacer un pivot dinamico. Puedes
hacerlo en tu aplicacion o herramienta de reporte, o usar sql dinamico. Si
usas sql dinamico, ten en cuenta sus implicaciones, principalmente la
inyeccion de codigo sql. La semana pasada se publico una noticia de que la
sede de Microsoft en UK (Inglaterra), fue atacada por un hacker mediante el
uso de esta tecnica.

http://www.infoworld.com/article/07...ack_1.html

Aqui te expongo un ejemplo, pero en realidad debes validar que no se inyecte
codigo sql atraves de los valores de la columna que se usa para la
concatenacion.

use northwind
go

create table dbo.t1 (
CampoCodigoPieza varchar(15),
CampoDescripcionPieza varchar(50)
)
go

insert into dbo.t1 values('ABV3456', 'Pantalones Azules')
insert into dbo.t1 values('AVBG567', 'Pantalones Grines')
insert into dbo.t1 values('AGH5678', 'Pantalones Verdes')
go

create table dbo.t2 (
CampoNombreCiente varchar(25),
CampoPiezaComprada varchar(15)
)
go

insert into dbo.t2 values('Jorge', 'ABV3456')
insert into dbo.t2 values('Carlos', 'AGH5678')
insert into dbo.t2 values('Jorge', 'AVBG567')
insert into dbo.t2 values('Pedro', 'ABV3456')
go

declare @sql nvarchar(max)
declare @values nvarchar(max)

set @values = stuff(
(
select
',[' + CampoDescripcionPieza + ']'
from
(
select distinct
a.CampoDescripcionPieza
from
dbo.t1 as a
inner join
dbo.t2 as b
on a.CampoCodigoPieza = b.CampoPiezaComprada
) as t
order by
CampoDescripcionPieza
for xml path('')
), 1, 1, '')

set @sql = N'
select
*
from
(
select
b.CampoNombreCiente,
a.CampoDescripcionPieza
from
dbo.t1 as a
inner join
dbo.t2 as b
on a.CampoCodigoPieza = b.CampoPiezaComprada
) as c
pivot
(count(CampoDescripcionPieza) for CampoDescripcionPieza in (' + @values +
N')) as d'

exec sp_executesql @sql
go

drop table dbo.t1, dbo.t2
go

Puedes leer mas sobre "pivot dinamico" en el libro:

Inside Microsoft® SQL Server™ 2005: T-SQL Programming
by Itzik Ben-Gan - (Solid Quality Learning), Dejan Sarka, Roger Wolter


AMB

"Pedro" wrote:

Ok, pero se presenta un problema con lo que me pasas:

en la parte del codigo donde pone:
([Pantalones
Azules], [Pantalones Verdes], [Pantalones Grines])
Se ha deconocer y picar en el codigo del script todos los tipos de
pantalones que tenermos, si mañana ponen un nuevo tipo de pantalon hay que
añadirlo amano en el cript.
Hay alguna forma de que tome todod los tipos de pantalon que tenemos en la
Tabla1, y si se añaden nuevos tipos de pantalon, la select con usa el pivot
los tenga enecuenta ya que este escript formara parte de un proceso
diario...

Gracias

"Alejandro Mesa" wrote:

> Hola Pedro,
>
> Trata:
>
> use northwind
> go
>
> create table dbo.t1 (
> CampoCodigoPieza varchar(15),
> CampoDescripcionPieza varchar(50)
> )
> go
>
> insert into dbo.t1 values('ABV3456', 'Pantalones Azules')
> insert into dbo.t1 values('AVBG567', 'Pantalones Grines')
> insert into dbo.t1 values('AGH5678', 'Pantalones Verdes')
> go
>
> create table dbo.t2 (
> CampoNombreCiente varchar(25),
> CampoPiezaComprada varchar(15)
> )
> go
>
> insert into dbo.t2 values('Jorge', 'ABV3456')
> insert into dbo.t2 values('Carlos', 'AGH5678')
> insert into dbo.t2 values('Jorge', 'AVBG567')
> insert into dbo.t2 values('Pedro', 'ABV3456')
> go
>
> select
> *
> from
> (
> select
> b.CampoNombreCiente,
> a.CampoDescripcionPieza
> from
> dbo.t1 as a
> inner join
> dbo.t2 as b
> on a.CampoCodigoPieza = b.CampoPiezaComprada
> ) as c
> pivot
> (count(CampoDescripcionPieza) for CampoDescripcionPieza in ([Pantalones
> Azules], [Pantalones Verdes], [Pantalones Grines])) as d
> go
>
> drop table dbo.t1, dbo.t2
> go
>
>
> AMB
>
>
> "Pedro" wrote:
>
> > Hola
> >
> > Estoy con un script.
> > Esplico que quiero hacer, resumiendo:
> >
> > Tengo 2 tablas:
> >
> > Tabla1 :
> > CampoCodigoPieza CampoDescripcionPieza
> > ABV3456 Pantalones Azules
> > AVBG567 Pantalones Grines
> > AGH5678 Pantalones Verdes
> > ...
> >
> >
> > Tabla2 :
> > CampoNombreCiente CampoPiezaComprada
> > Jorge ABV3456
> > Carlos AGH5678
> > Jorge ABV3456
> > Pedro ABV3456
> >
> >
> > Quiero obtener un Script que me genere una tabla3 de la forma:
> > CampoCiente PantalonAzules PantalonVerdes PantalonGris
> > Jorge 1 0 1
> >
> > Carlos 0 1 0
> >
> > Pedro 1 0 0
> >
> > Que ponga 1 si comapra ese modelo, 0 si no compara ese mododelo.
> >
> > He estado mirando de hacerlo mediante el PIVOT pero no me vale de la forma:
> >
> > Select CampoCodigoPieza as campocliente, [ABV3456] as "PantalonAzules",
> > [AVBG567] as "PantalonVerdes", [AGH5678] as "PantalonGris"
> > from tabla1
> > PIVOT ( for tabla3 in ([ABV3456], [AVBG567], [AGH5678]) as pvt
> >
> > Pero no me vale ya que me faltaria un campo en la tabla1 del numero de
> > pantalos que compran de cada tipo. y de este campo habria que hacer un sum()
> > y ponerlo delante del for
> >
> > La tabla que me quiero crear mediante un scrip, quiero que si algun dia me
> > añaden en la tabla1 un nuevo registro la final (tabla3) lo tenga en cuenta y
> > me aparezca.
> >
> > Alguna idea.
> > Gracias
> >
Respuesta Responder a este mensaje
#4 Carlos M. Calvelo
09/07/2007 - 11:16 | Informe spam
On 8 jul, 00:46, Pedro wrote:
Hola

Estoy con un script.
Esplico que quiero hacer, resumiendo:

Tengo 2 tablas:

Tabla1 :
CampoCodigoPieza CampoDescripcionPieza
ABV3456 Pantalones Azules
AVBG567 Pantalones Grines
AGH5678 Pantalones Verdes
...

Tabla2 :
CampoNombreCiente CampoPiezaComprada
Jorge ABV3456
Carlos AGH5678
Jorge ABV3456
Pedro ABV3456

Quiero obtener un Script que me genere una tabla3 de la forma:
CampoCiente PantalonAzules PantalonVerdes PantalonGris
Jorge 1 0 1

Carlos 0 1 0

Pedro 1 0 0

Que ponga 1 si comapra ese modelo, 0 si no compara ese mododelo.

He estado mirando de hacerlo mediante el PIVOT pero no me vale de la forma:

Select CampoCodigoPieza as campocliente, [ABV3456] as "PantalonAzules",
[AVBG567] as "PantalonVerdes", [AGH5678] as "PantalonGris"
from tabla1
PIVOT ( for tabla3 in ([ABV3456], [AVBG567], [AGH5678]) as pvt

Pero no me vale ya que me faltaria un campo en la tabla1 del numero de
pantalos que compran de cada tipo. y de este campo habria que hacer un sum()
y ponerlo delante del for

La tabla que me quiero crear mediante un scrip, quiero que si algun dia me
añaden en la tabla1 un nuevo registro la final (tabla3) lo tenga en cuenta y
me aparezca.

Alguna idea.
Gracias



Hola Pedro,

Una alternativa a la solución de Alejandro (con un cursor):

create table Piezas (
Codigo varchar(15) not null primary key,
Descripcion varchar(50) not null unique
)

create table Compras (
Cliente varchar(25) not null,
Pieza varchar(15) not null references Piezas(Codigo)
)

insert into Piezas values('ABV3456', 'Pantalones Azules')
insert into Piezas values('AVBG567', 'Pantalones Grises')
insert into Piezas values('AGH5678', 'Pantalones Verdes')
insert into Piezas values('XXX0000', 'Pajaritas de Colores :)')

insert into Compras values('Jorge', 'ABV3456')
insert into Compras values('Carlos', 'AGH5678')
insert into Compras values('Jorge', 'AVBG567')
insert into Compras values('Pedro', 'ABV3456')
insert into Compras values('Pedro', 'ABV3456') -- duplicado!?


declare @sum_cases varchar(8000),
@codigo varchar(15),
@descripcion varchar(50)

set @sum_cases = ''

declare cursorPiezas cursor for
select Codigo, Descripcion from Piezas

open cursorPiezas

fetch next from cursorPiezas into @codigo, @descripcion
while @@fetch_status = 0
begin
set @sum_cases = @sum_cases +
',sum(case c.Pieza when ''' + @codigo +
''' then 1 else 0 end) as ' + '''' + @descripcion + ''''
fetch next from cursorPiezas into @codigo, @descripcion
end

close cursorPiezas
deallocate cursorPiezas

exec('select c.Cliente' + @sum_cases +
' from compras c group by c.cliente')

drop table compras
drop table piezas


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