Sql dinámico.

29/08/2006 - 20:27 por Pedroafa | Informe spam
Hola a todos.

Quiero hacer una consulta que me calcule la rentabilidad de cada año de un
fondo de inversión. Tengo una una tabla con los valores que ha ido tomando
ese fondo a lo largo de los años, tiene un campo fecha y otro valor. Como no
se me ocurria una consulta sql para resolver este problema lo hice a través
de crear la control dinámicamente en un procedimiento almacenado, lo que he
hecho, funcionar funciona. Lo que quiero saber, es si es el mejor medio para
resolverlo y si lo he hecho bien.

Este es el resultado:
Año Estado Rentabilidad
1999 verde 1.24

2000 verde 3.36

2001 verde 4.07

2002 rojo 2.90

2003 rojo 1.76

2004 rojo 1.40

2005 rojo 1.34

2006 rojo 1.09


ALTER PROCEDURE [dbo].[CalcularRentabilidadFondo]

@idfondo int

AS

BEGIN



DECLARE @year CHAR(4), @query VARCHAR(8000), @countQuery int

DECLARE @beforeRentabilidad DECIMAL(14,2),@rentabilidad DECIMAL(14,2)

DECLARE @color VARCHAR(5)



SET @query = ''

SET @countQuery = 0

SET @beforeRentabilidad = 0



DECLARE years_cursor CURSOR FOR SELECT year(fecha)

FROM Historicos

GROUP BY year(fecha),idfondo

HAVING idfondo = @idfondo ORDER BY year(fecha)



OPEN years_cursor

FETCH NEXT FROM years_cursor INTO @year

WHILE @@FETCH_STATUS = 0

BEGIN



DECLARE @valorInicio DECIMAL(14,6), @valorFinal DECIMAL(14,6)



SELECT TOP 1 @valorInicio = valorliquidativo FROM Historicos

WHERE idfondo =
@idfondo AND year(fecha)=@year

ORDER BY fecha



SELECT TOP 1 @valorFinal = valorliquidativo FROM Historicos

WHERE idfondo =
@idfondo AND year(fecha)=@year

ORDER BY fecha DESC



/*Calcular la rentabilidad para el año*/

SELECT @rentabilidad = ((@valorFinal - @valorInicio) / @valorInicio)
* 100



/*Calcular el color*/

IF @beforeRentabilidad > @rentabilidad

SET @color = 'rojo'

ELSE IF @beforeRentabilidad < @rentabilidad

SET @color = 'verde'

ELSE

SET @color = 'azul'



IF @countQuery = 0

SET @query = @query + ' SELECT Ano=' +
RTRIM(LTRIM(CONVERT(VARCHAR,@year))) + ' ,Estado=''' + @color + '''
,Valor=' + RTRIM(LTRIM(CONVERT(VARCHAR,@rentabilidad)))

ELSE

SET @query = @query + ' UNION SELECT Ano=' +
RTRIM(LTRIM(CONVERT(VARCHAR,@year))) + ' ,Estado=''' + @color + '''
,Valor=' +

RTRIM(LTRIM(CONVERT(VARCHAR,@rentabilidad)))



SET @countQuery = @countQuery + 1

SET @beforeRentabilidad = @rentabilidad



FETCH NEXT FROM years_cursor INTO @year

END



EXEC (@query)



CLOSE years_cursor

DEALLOCATE years_cursor



END



Espero vuestras valoraciones, muchas gracias.

Un Saludo, Pedro.

Preguntas similare

Leer las respuestas

#6 Alejandro Mesa
30/08/2006 - 14:47 | Informe spam
Pedroafa,

Muy pero muy dificil darte una sugerencia si lo unico que tenemos es un
codigo que debemos leer y entender. Por que no nos ayudas tambien a nosotros
y nos muestras la estructura de la tabla [historicos], incluyendo
restricciones e indices. Tambien puedes incluir unos datos de ejemplo junto
con los resultados esperados.

create table dbo.t1 (
idfondo int not null,
fecha datetime,
valorliquidativo money
)
go

insert into dbo.t1 values(1, '20040101', 1)
insert into dbo.t1 values(1, '20040201', 6)
insert into dbo.t1 values(1, '20050101', 2)
insert into dbo.t1 values(1, '20050201', 1)
insert into dbo.t1 values(1, '20050301', 1)
insert into dbo.t1 values(1, '20050401', 5)
insert into dbo.t1 values(1, '20060101', 1)
insert into dbo.t1 values(1, '20060201', 3)
insert into dbo.t1 values(1, '20060301', 1.5)
go

create function dbo.ufn_get_stats (@idfondo int)
returns table
as
return (
select
h1.idfondo,
h2.[year],
max(case when h1.fecha = h2.min_fecha then h1.valorliquidativo end) as
valorInicio,
max(case when h1.fecha = h2.max_fecha then h1.valorliquidativo end) as
valorFinal,
(
(
max(case when h1.fecha = h2.max_fecha then h1.valorliquidativo end) -
max(case when h1.fecha = h2.min_fecha then h1.valorliquidativo end)
) /
nullif(
max(case when h1.fecha = h2.min_fecha then h1.valorliquidativo end), 0)
) as rentabilidad
from
dbo.t1 as h1
inner join
(
select idfondo, year(fecha) as [year], min(fecha) as min_fecha, max(fecha)
as max_fecha
from dbo.t1
where idfondo = @idfondo
group by idfondo, year(fecha)
) as h2(idfondo, [year], min_fecha, max_fecha)
on h1.idfondo = h2.idfondo
and (h1.fecha = h2.min_fecha or h1.fecha = h2.max_fecha)
where
h1.idfondo = @idfondo
group by
h1.idfondo,
h2.[year]
)
go

select
*
from
dbo.ufn_get_stats(1)
order by
[year]
go

select
b.*,
case
when b.rentabilidad > isnull(a.rentabilidad, 0) then 'verde'
when b.rentabilidad < isnull(a.rentabilidad, 0) then 'rojo'
else 'azul'
end as estado
from
dbo.ufn_get_stats(1) as a
right join
dbo.ufn_get_stats(1) as b
on a.[year] = b.[year] - 1
order by
b.[year]
go

drop function dbo.ufn_get_stats
go

drop table dbo.t1
go


AMB

"Pedroafa" wrote:

Hola a todos.

Quiero hacer una consulta que me calcule la rentabilidad de cada año de un
fondo de inversión. Tengo una una tabla con los valores que ha ido tomando
ese fondo a lo largo de los años, tiene un campo fecha y otro valor. Como no
se me ocurria una consulta sql para resolver este problema lo hice a través
de crear la control dinámicamente en un procedimiento almacenado, lo que he
hecho, funcionar funciona. Lo que quiero saber, es si es el mejor medio para
resolverlo y si lo he hecho bien.

Este es el resultado:
Año Estado Rentabilidad
1999 verde 1.24

2000 verde 3.36

2001 verde 4.07

2002 rojo 2.90

2003 rojo 1.76

2004 rojo 1.40

2005 rojo 1.34

2006 rojo 1.09


ALTER PROCEDURE [dbo].[CalcularRentabilidadFondo]

@idfondo int

AS

BEGIN



DECLARE @year CHAR(4), @query VARCHAR(8000), @countQuery int

DECLARE @beforeRentabilidad DECIMAL(14,2),@rentabilidad DECIMAL(14,2)

DECLARE @color VARCHAR(5)



SET @query = ''

SET @countQuery = 0

SET @beforeRentabilidad = 0



DECLARE years_cursor CURSOR FOR SELECT year(fecha)

FROM Historicos

GROUP BY year(fecha),idfondo

HAVING idfondo = @idfondo ORDER BY year(fecha)



OPEN years_cursor

FETCH NEXT FROM years_cursor INTO @year

WHILE @@FETCH_STATUS = 0

BEGIN



DECLARE @valorInicio DECIMAL(14,6), @valorFinal DECIMAL(14,6)



SELECT TOP 1 @valorInicio = valorliquidativo FROM Historicos

WHERE idfondo =
@idfondo AND year(fecha)=@year

ORDER BY fecha



SELECT TOP 1 @valorFinal = valorliquidativo FROM Historicos

WHERE idfondo =
@idfondo AND year(fecha)=@year

ORDER BY fecha DESC



/*Calcular la rentabilidad para el año*/

SELECT @rentabilidad = ((@valorFinal - @valorInicio) / @valorInicio)
* 100



/*Calcular el color*/

IF @beforeRentabilidad > @rentabilidad

SET @color = 'rojo'

ELSE IF @beforeRentabilidad < @rentabilidad

SET @color = 'verde'

ELSE

SET @color = 'azul'



IF @countQuery = 0

SET @query = @query + ' SELECT Ano=' +
RTRIM(LTRIM(CONVERT(VARCHAR,@year))) + ' ,Estado=''' + @color + '''
,Valor=' + RTRIM(LTRIM(CONVERT(VARCHAR,@rentabilidad)))

ELSE

SET @query = @query + ' UNION SELECT Ano=' +
RTRIM(LTRIM(CONVERT(VARCHAR,@year))) + ' ,Estado=''' + @color + '''
,Valor=' +

RTRIM(LTRIM(CONVERT(VARCHAR,@rentabilidad)))



SET @countQuery = @countQuery + 1

SET @beforeRentabilidad = @rentabilidad



FETCH NEXT FROM years_cursor INTO @year

END



EXEC (@query)



CLOSE years_cursor

DEALLOCATE years_cursor



END



Espero vuestras valoraciones, muchas gracias.

Un Saludo, Pedro.





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