¿Hay un estándar para el cálculo de function agregada de SQL?

¿Existe un estándar en la implementación SQL para llamadas múltiples a la misma function agregada en la misma consulta?

Por ejemplo, considere el siguiente ejemplo, basado en un esquema de ejemplo popular:

SELECT Customer,SUM(OrderPrice) FROM Orders GROUP BY Customer HAVING SUM(OrderPrice)>1000 

Presumiblemente, se necesita time de cálculo para calcular el valor de SUM (OrderPrice). ¿Se incurre en este costo para cada reference a la function agregada o se almacena el resultado para una consulta en particular?

O bien, ¿no hay un estándar para la implementación del motor SQL para este caso?

Aunque he trabajado con muchos DBMS diferentes, solo le mostraré el resultado de probar esto en SQL Server. Considere esta consulta, que incluso incluye un CAST en la expresión. Mirando el plan de consulta, la expresión sum(cast(number as bigint)) solo se toma una vez, que se define como DEFINE:([Expr1005]=SUM([Expr1006])) .

 set showplan_text on select type, sum(cast(number as bigint)) from master..spt_values group by type having sum(cast(number as bigint)) > 100000 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |--Filter(WHERE:([Expr1005]>(100000))) |--Hash Match(Aggregate, HASH:([Expr1004]), RESIDUAL:([Expr1004] = [Expr1004]) DEFINE:([Expr1005]=SUM([Expr1006]))) |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(nchar(3),[mssqlsystemresource].[sys].[spt_values].[type],0), [Expr1006]=CONVERT(bigint,[mssqlsystemresource].[sys].[spt_values].[number],0))) |--Index Scan(OBJECT:([mssqlsystemresource].[sys].[spt_values].[ix2_spt_values_nu_nc])) 

Puede que no sea muy obvio, dado que no muestra el resultado de SELECCIONAR, así que he agregado un *10 a la consulta a continuación. Observe que ahora incluye un paso adicional DEFINE:([Expr1006]=[Expr1005]*(10)) (los pasos se ejecutan de abajo hacia arriba), lo que demuestra que la nueva expresión requería realizar un cálculo adicional. Sin embargo, incluso esto está optimizado, ya que no recalcula toda la expresión; ¡simplemente está tomando Expr1005 y multiplicando eso por 10!

 set showplan_text on select type, sum(cast(number as bigint))*10 from master..spt_values group by type having sum(cast(number as bigint)) > 100000 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |--Compute Scalar(DEFINE:([Expr1006]=[Expr1005]*(10))) |--Filter(WHERE:([Expr1005]>(100000))) |--Hash Match(Aggregate, HASH:([Expr1004]), RESIDUAL:([Expr1004] = [Expr1004]) DEFINE:([Expr1005]=SUM([Expr1007]))) |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(nchar(3),[mssqlsystemresource].[sys].[spt_values].[type],0), [Expr1007]=CONVERT(bigint,[mssqlsystemresource].[sys].[spt_values].[number],0))) |--Index Scan(OBJECT:([mssqlsystemresource].[sys].[spt_values].[ix2_spt_values_nu_nc])) 

Es muy probable que todos los demás DBMS funcionen también, al less teniendo en count los más importantes, es decir, PostgreSQL, Sybase, Oracle, DB2, Firebird, MySQL.