registros - sql agrupar y sumar
¿Hay una función de PRODUCTO como si hubiera una función de SUMA en Oracle SQL? (6)
Aquí hay otra manera de hacerlo. Esta es definitivamente la forma más larga de hacerlo, pero fue parte de un proyecto divertido.
Tienes que volver a la escuela para esta, jaja. La clave para recordar aquí es que LOG es el inverso de Exponent.
LOG10 (X * Y) = LOG10 (X) + LOG10 (Y)
o
ln (X * Y) = ln (X) + ln (Y) (ln = registro natural, o simplemente Log base 10)
Ejemplo
Si X = 5 e Y = 6
X * Y = 30
ln (5) + ln (6) = 3.4
ln (30) = 3.4
e ^ 3.4 = 30, también lo hace 5 x 6
EXP (3.4) = 30
Así que arriba, si cada uno de 5 y 6 ocupa una fila en la tabla, tomamos el registro natural de cada valor, sumamos las filas, luego tomamos el exponente de la suma para obtener 30.
A continuación se muestra el código en una declaración SQL para SQL Server. Es probable que se requiera cierta edición para que se ejecute en Oracle. Espero que no sea una gran diferencia, pero sospecho que al menos la declaración CASE no es la misma en Oracle. Notarás algunas cosas adicionales para probar si el signo de la fila es negativo.
CREATE TABLE DUAL (VAL INT NOT NULL)
INSERT DUAL VALUES (3)
INSERT DUAL VALUES (5)
INSERT DUAL VALUES (2)
SELECT
CASE SUM(CASE WHEN SIGN(VAL) = -1 THEN 1 ELSE 0 END) % 2
WHEN 1 THEN -1
ELSE 1
END
* CASE
WHEN SUM(VAL) = 0 THEN 0
WHEN SUM(VAL) IS NOT NULL THEN EXP(SUM(LOG(ABS(CASE WHEN SIGN(VAL) <> 0 THEN VAL END))))
ELSE NULL
END
* CASE MIN(ABS(VAL)) WHEN 0 THEN 0 ELSE 1 END
AS PRODUCT
FROM DUAL
Tengo un compañero de trabajo buscando esto, y no recuerdo haber encontrado algo así.
¿Hay alguna técnica razonable que te permita simularla?
SELECT PRODUCT(X)
FROM
(
SELECT 3 X FROM DUAL
UNION ALL
SELECT 5 X FROM DUAL
UNION ALL
SELECT 2 X FROM DUAL
)
produciría 30
Hay muchas implicaciones diferentes de "SQL". Cuando dice "does sql have" se refiere a una versión ANSI específica de SQL, o una implementación específica del proveedor. La respuesta de DavidB es aquella que funciona en algunos entornos diferentes que he probado pero, dependiendo de su entorno, puede escribir o encontrar una función exactamente igual a la que está solicitando. Digamos que estaba usando Microsoft SQL Server 2005, entonces una posible solución sería escribir un agregador personalizado en el código .net llamado PRODUCT que permitiría que su consulta original funcionara exactamente como la había escrito.
Parece que puede programar esta funcionalidad en Oracle. Esta técnica puede soportar el paralelismo, a diferencia de la técnica MS-SQL en mi otra respuesta. Spiffy.
DECLARE @a int
SET @a = 1
-- re-assign @a for each row in the result
-- as what @a was before * the value in the row
SELECT @a = @a * amount
FROM theTable
Hay una manera de hacer cadena concat que es similar:
DECLARE @b varchar(max)
SET @b = ""
SELECT @b = @b + CustomerName
FROM Customers
En c # puede que tenga que hacer:
SELECT EXP(SUM(LOG([col])))
FROM table;
select exp(sum(ln(col)))
from table;
editar:
si col siempre> 0