¿Por qué no hay ninguna function agregada de PRODUCT en SQL?

Estoy buscando algo como SELECT PRODUCT(table.price) FROM table GROUP BY table.sale similar a cómo funciona SUM .

¿Me perdí algo en la documentation o realmente no hay ninguna function de PRODUCT ?

Si es así, ¿por qué no?

Nota: busqué la function en postgres, mysql y mssql y no encontré ninguna, así que asumí que todos los sql no son compatibles.

No hay ninguna function de set de PRODUCT en el estándar SQL. Sin embargo, parece ser un candidato digno (a diferencia de, por ejemplo, una function de set CONCATENATE : no es una buena CONCATENATE para SQL, por ejemplo, el tipo de datos resultante implicaría multivalos y plantearía un problema con respecto a la primera forma normal).

Los Estándares SQL apuntan a consolidar la funcionalidad de los productos SQL alnetworkingedor de 1990 y a proporcionar un "liderazgo de pensamiento" en el desarrollo futuro. En resumen, documentan lo que SQL hace y lo que SQL debe hacer. La ausencia de la function de set de PRODUCT sugiere que en 1990 ningún proveedor era digno de ser incluido y que no ha habido interés académico en introducirlo en el Estándar.

Por supuesto, los vendedores siempre han intentado agregar su propia funcionalidad, actualmente como extensiones a estándares en lugar de tangentally. No recuerdo haber visto una function de set de PRODUCT (o incluso la demanda de una) en ninguno de los productos de SQL que he usado.

En cualquier caso, la solución alternativa es bastante simple al usar funciones escalares de log y exp (y lógica para manejar los negativos) con la function SUM set; ver la respuesta de @gbn para un código de muestra. Sin embargo, nunca tuve que hacer esto en una aplicación de negocios.

En conclusión, mi mejor estimación es que los usuarios finales de SQL no exigen una function de set de PRODUCT ; además, que cualquier persona con interés académico probablemente encontraría la solución alternativa aceptable (es decir, no valoraría el azúcar sintáctico que proporcionaría una function del set de PRODUCT ).

Fuera de interés, de hecho hay demanda en SQL Server Land para nuevas funciones de set, pero para aquellas de la variedad de funciones de window (y Standard SQL, también). Para get más información, incluida la forma de involucrarse en una mayor demanda de conducción, consulte el blog de Itzik Ben-Gan .

Para MSSQL puedes usar esto. Puede ser adoptado para otras plataforms: es solo matemática y agrega logaritmos.

 SELECT GrpID, CASE WHEN MinVal = 0 THEN 0 WHEN Neg % 2 = 1 THEN -1 * EXP(ABSMult) ELSE EXP(ABSMult) END FROM ( SELECT GrpID, --log of +ve row values SUM(LOG(ABS(NULLIF(Value, 0)))) AS ABSMult, --count of -ve values. Even = +ve result. SUM(SIGN(CASE WHEN Value < 0 THEN 1 ELSE 0 END)) AS Neg, --anything * zero = zero MIN(ABS(Value)) AS MinVal FROM Mytable GROUP BY GrpID ) foo 

Tomado de mi respuesta aquí: SQL Server Query – multiplicación de groupwise

No sé por qué no hay ninguno, pero (tenga más cuidado con los numbers negativos) puede usar loggings y exponentes para hacer:

 select exp (sum (ln (table.price))) from table ... 

Puede realizar una function de agregado de producto, pero tiene que hacer las matemáticas usted mismo, así …

 SELECT Exp(Sum(IIf(Abs([Num])=0,0,Log(Abs([Num])))))*IIf(Min(Abs([Num]))=0,0,1)*(1-2*(Sum(IIf([Num]>=0,0,1)) Mod 2)) AS P FROM Table1 

Fuente: http://productfunctionsql.codeplex.com/

Hay un buen truco en T-SQL (no estoy seguro si es ANSI) que permite concatenar valores de cadena de un set de filas en una variable. Parece que funciona para multiplicar también:

 declare @Floats as table (value float) insert into @Floats values (0.9) insert into @Floats values (0.9) insert into @Floats values (0.9) declare @multiplier float = null select @multiplier = isnull(@multiplier, '1') * value from @Floats select @multiplier 

Esto puede ser potencialmente más numéricamente estable que la solución log / exp.

Creo que es porque ningún sistema de numeración puede acomodar muchos productos. Como las bases de datos están diseñadas para una gran cantidad de loggings, un producto de 1000 numbers sería súper masivo y, en el caso de numbers en coma flotante, el error propagado sería enorme.

También tenga en count que el uso de logging puede ser una solución peligrosa. Aunque matemáticamente log (a * b) = log (a) * log (b), podría no estar en las computadoras ya que no estamos tratando con numbers reales. Si calcula 2 ^ (log (a) + log (b)) en lugar de a * b, puede get resultados inesperados. Por ejemplo:

SELECCIONAR 9999999999 * 99999999974482, EXP (REGISTRO (9999999999) + REGISTRO (99999999974482))

en Sql Server devuelve

999999999644820000025518, 9.99999999644812E + 23

Así que mi punto es cuando estás tratando de hacer el producto, hazlo con cuidado y la testing es pesada.

Una forma de lidiar con este problema (si está trabajando en un lenguaje de scripting) es usar la function group_concat. Por ejemplo, SELECT group_concat(table.price) FROM table GROUP BY table.sale

Esto devolverá una cadena con todos los precios para el mismo valor de venta, separados por una coma. Luego, con un analizador, puede get cada precio y hacer una multiplicación. (En php incluso puedes usar la function array_networkinguce, de hecho, en el manual de php.net obtienes un ejemplo adecuado).

Aclamaciones