usuario - listado de funciones en sql server
¿Por qué no hay ninguna función agregada de PRODUCT en SQL? (7)
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 documentación o realmente no hay ninguna función de PRODUCT
?
Si es así, ¿por qué no?
Nota: busqué la función en postgres, mysql y mssql y no encontré ninguna, así que asumí que todos los sql no son compatibles.
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 registros, un producto de 1000 números sería súper masivo y en el caso de números en coma flotante, el error propagado sería enorme.
También tenga en cuenta que el uso de registro 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 números reales. Si calcula 2 ^ (log (a) + log (b)) en lugar de a * b, puede obtener 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 prueba es pesada.
Hay un buen truco en T-SQL (no estoy seguro si es ANSI) que permite concatenar valores de cadena de un conjunto 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.
No hay ninguna función de conjunto de PRODUCT
en el estándar SQL. Sin embargo, parece ser un candidato digno (a diferencia de, por ejemplo, una función de conjunto 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 alrededor 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 función de conjunto 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 función de conjunto de PRODUCT
(o incluso la demanda de una) en ninguno de los productos de SQL que he usado.
En cualquier caso, el trabajo en general es bastante simple usando funciones escalares de log
y exp
(y lógica para manejar negativos) con la función 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 función de conjunto 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 función del conjunto de PRODUCT
).
Fuera de interés, de hecho hay demanda en SQL Server Land para nuevas funciones de conjunto, pero para aquellas de la variedad de funciones de ventana (y Standard SQL, también). Para obtener más información, incluida la forma de involucrarse en una mayor demanda de conducción, consulte el blog de Itzik Ben-Gan .
No sé por qué no hay ninguno, pero (tenga más cuidado con los números negativos) puede usar registros y exponentes para hacer:
select exp (sum (ln (table.price))) from table ...
Para MSSQL puedes usar esto. Puede ser adoptado para otras plataformas: 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 en grupo
Puede realizar una función 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
Una forma de lidiar con este problema (si está trabajando en un lenguaje de scripting) es usar la función 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 obtener cada precio y hacer una multiplicación. (En php incluso puedes usar la función array_reduce, de hecho en el manual de php.net obtienes un ejemplo adecuado).
Aclamaciones