Crosstab

25/02/2005 - 18:34 por Florencia | Informe spam
Hola a todos, me dijeron que con el sql podía hacer algo
como un crosstab, le cuetno que es lo que necesito porque
lo que vi en la ayuda es muy fijo y necesito algo mas
variable.
tengo una tabla que tiene la siguiente forma:
Empresa CodigoConcepto DescripcionConcepto Importe... etc.
1 1 Caja 20
2 1 Caja 35
2 2 Bancos 50
3 1 Caja 40

donde la cantidad de filas es variable por ser la cantidad
de empresas variables, lo que yo necesito es obtener la
información de la siguiente manera

DescripcionConcepto Empresa1 Empresa2 Empresa3... EmpresaN

Caja 20 35 40 0
Bancos 0 50 0 0

Se entiendo? desde ya muchisimas gracias
 

Leer las respuestas

#1 Alejandro Mesa
25/02/2005 - 20:07 | Informe spam
Florencia,

Se puede hacer pero es un poco engorroso, actualmente no existe una
sentencia para ello. Esta facilidad viene mejor implementada en la nueva
version.

Voy a tratar de emplicar como hacerlo.

Si quisieramos contar cuantos productos existen en ordenes puestas por
clientes de Argentina por cada categoria, seria algo asi como:

select
c.categoryname,
count(case when cu.country = 'Argentina' then 1 end) as 'Argentina'
from
customers cu
inner join
orders as oh
on cu.customerid = oh.customerid
inner join
[order details] as od
on oh.orderid = od.orderid
inner join
products as p
on od.productid = p.productid
inner join
categories as c
on p.categoryid = c.categoryid
group by
c.categoryname
order by
c.categoryname

Como no sabemos de antemano cuantos paises hay, entonces esta sentencia
"select" la tenemos que armar de forma dinamica.

use northwind
go

declare @country nvarchar(15)
declare @sql varchar(8000)

set @sql = 'select c.categoryname'

declare countries cursor local fast_forward
for
select distinct country from customers order by country

open countries

while 1 = 1
begin
fetch next from countries into @country

if @@error != 0 or @@fetch_status != 0 break

set @sql = @sql + ', count(case when cu.country = ''' + cast(@country as
varchar(15)) + ''' then 1 end) as ''' + cast(@country as varchar(15)) + ''''
end

close countries
deallocate countries

set @sql = @sql + 'from
customers cu
inner join
orders as oh
on cu.customerid = oh.customerid
inner join
[order details] as od
on oh.orderid = od.orderid
inner join
products as p
on od.productid = p.productid
inner join
categories as c
on p.categoryid = c.categoryid
group by
c.categoryname order by c.categoryname'

print @sql
print datalength(@sql)

execute(@sql)
go

Cuando ejecutes el script, fijate en la sentencia "select" que se genera.
Hay muchos inconvenientes en esta solucion. Como puedes ver, uno es el use de
cursores. Otro seria la longitud de la variable @sql es de 8000 caracteres,
si la sentencia es mayor, entonces necesitas cambiar un poco el codigo y usar
multiples variables para almacenar la sentencia en ellas y ejecutarlas de la
forma:

exec (@sql1 + @sql2 + ... + @sqln)

Otra gran inconveniencia de esta solucion es el uso de sql dinamico, pues
tendrias que darle permiso de lectura sobre las tablas involucradas a cada
usuario que va a ejecutar el procedimiento almacenado. Tambien sql server
tiene que chequear la sentencia armada y compilarla.

Otra solucion seria crear una tabla temporal con una columna para almacenar
la categoria y una columna por cada pais. Luego habria que calcular los
valores por pais y categoria. De todas maneras esto implicaria el uso
cursores y sql dinamico.


AMB

"Florencia" wrote:

Hola a todos, me dijeron que con el sql podía hacer algo
como un crosstab, le cuetno que es lo que necesito porque
lo que vi en la ayuda es muy fijo y necesito algo mas
variable.
tengo una tabla que tiene la siguiente forma:
Empresa CodigoConcepto DescripcionConcepto Importe... etc.
1 1 Caja 20
2 1 Caja 35
2 2 Bancos 50
3 1 Caja 40

donde la cantidad de filas es variable por ser la cantidad
de empresas variables, lo que yo necesito es obtener la
información de la siguiente manera

DescripcionConcepto Empresa1 Empresa2 Empresa3... EmpresaN

Caja 20 35 40 0
Bancos 0 50 0 0

Se entiendo? desde ya muchisimas gracias


Preguntas similares