Simular
función de agregado que multiplique en lugar de sumar
En
el grupo de noticias microsoft.public.es.sqlserver se planteó la
siguiente cuestión:
Necesito
multiplicar todos los valores de una expresión entre sí,
algo
similar a la función SUM() pero multiplicando.
Es posible hacer esto mediante alguna función en SQL 2000 ???
ARTICULO POSICION FACTOR
780 1 0.94
780 2 0.95
780 3 0.91
Resultado:
ARTICULO FACTOR
780 0.81263
A continuación
la respuesta que ofreció Alejandro Mesa a dicha cuestión
Hola
Gustavo,
Una vez lei una solucion
brillante para este problema, en el grupo en Ingles y lo voy a compartir
con ustedes. Como todos sabemos, en SQL Server no contamos con una funcion
de grupo para multiplicacion, aunque tambien sabemos que en la version
2005 podemos crear funciones de grupo usando CLR. Pero bueno, estamos
hablando de la vesion 2000, en la cual no tenemos CLR.
La solucion se basa
en lo sgte, queremos el resultado de 0.94 * 0.95 * 0.9 y sabemos que el
logaritmo de la multiplicacion es igual a la suma de los logaritmos.
select log(0.94 * 0.95
* 0.91), log(0.94) + log(0.95) + log(0.91)
Sabemos que podemos
calcular la sum de los logaritmos usando la funcion de grupo SUM. Ahora
debemos transformar el resultado para alcanzar la multiplicacion, por
lo que aplicamos el antilogaritmo EXP() al resultado de la suma.
Vamos a verlo por
paso.
Queremos:
y = 0.94 * 0.95 * 0.91
y = x1 * x2 * x3
log(y) = log(x1) + log(x2)
+ log(x3)
La suma de los logaritmos
la sabemos calcular, asi que al resultado de la suma le aplicamos el antilogaritmo
para obtener "y".
log(y)
= x
Equivale a
10^x = y
exp(x) = y
Asi que la solucion
es aplicar la funcion EXP al resultado de la suma de los logaritmos y
ademas la funcion SUM nos permite agrupar.
declare
@t table (c1 int not null, c2 float not null)
-- 0.81263
insert into @t values(780, 0.94)
insert into @t values(780, 0.95)
insert into @t values(780, 0.91)
-- 24
insert into @t values(781, 2)
insert into @t values(781, 3)
insert into @t values(781, 4)
select c1, exp(sum(log(c2)))
from @t
group by
c1
go
AMB
|