SQL中的乘法聚合运算符

mae*_*sto 27 sql sql-server oracle

在SQL中有聚合运算符,如AVG,SUM,COUNT.为什么它没有乘法运算符?"MUL"或其他东西.

我想知道,Oracle,MSSQL,MySQL是否存在?如果没有,是否有解决方法会产生这种行为?

Ric*_*iwi 44

通过MUL,你的意思是逐步增加价值?

即使有100行的一些小尺寸(比如10s),你的MUL(列)也会溢出任何数据类型!由于错误/滥用的概率很高,而且使用范围非常有限,因此不需要是SQL标准.正如其他人已经表明的那样,有数学方法可以解决这个问题,就像使用标准(和常用)方法在SQL中进行棘手的计算有很多种方法一样.

样本数据:

Column
1
2
4
8

COUNT : 4 items (1 for each non-null)
SUM   : 1 + 2 + 4 + 8 = 15
AVG   : 3.75 (SUM/COUNT)
MUL   : 1 x 2 x 4 x 8 ? ( =64 )
Run Code Online (Sandbox Code Playgroud)

为了完整起见,Oracle,MSSQL,MySQL核心实现*

Oracle : EXP(SUM(LN(column)))   or  POWER(N,SUM(LOG(column, N)))
MSSQL  : EXP(SUM(LOG(column)))  or  POWER(N,SUM(LOG(column)/LOG(N)))
MySQL  : EXP(SUM(LOG(column)))  or  POW(N,SUM(LOG(N,column)))
Run Code Online (Sandbox Code Playgroud)
  • 在SQL Server中使用EXP/LOG时要小心,请注意返回类型http://msdn.microsoft.com/en-us/library/ms187592.aspx
  • POWER表单允许更大的数字(使用大于欧拉数的基数),并且在结果变得太大而无法使用POWER将其返回的情况下,您可以仅返回对数值并计算SQL查询之外的实际数字


*LOG(0)和LOG(-ve)未定义.下面仅显示如何在SQL Server中处理此问题.使用相同的概念可以找到其他SQL风格的等价物

create table MUL(data int)
insert MUL select 1 yourColumn union all
           select 2 union all
           select 4 union all
           select 8 union all
           select -2 union all
           select 0

select CASE WHEN MIN(abs(data)) = 0 then 0 ELSE
       EXP(SUM(Log(abs(nullif(data,0))))) -- the base mathematics
     * round(0.5-count(nullif(sign(sign(data)+0.5),1))%2,0) -- pairs up negatives
       END
from MUL
Run Code Online (Sandbox Code Playgroud)

配料:

  • 取数据的abs(),如果min为0,则乘以其他任何无效的结果,结果为0
  • 当数据为0时,NULLIF将其转换为null.abs(),log()都返回null,导致它被sum()排除
  • 如果数据不是0,则abs允许我们使用LOG方法将负数加倍 - 我们将跟踪其他地方的负面情况
  • 制定最终标志
    • sign(data)返回1 for >0,0 for 0-1 for <0.
    • 我们再添加0.5并再次取符号(),因此我们现在将0和1都归为1,并将-1归为-1.
    • 再次使用NULLIF从COUNT()中删除1,因为我们只需要计算负数.
    • % 2 反对count()的负数返回
    • - >如果有一个奇数的负数,则为> 1
    • - 如果有偶数个负数,则> 0
    • 更多数学技巧:我们取1或0关0.5,以便上述变为
    • - >(0.5-1=-0.5=> round to -1)如果有一个奇数个负数
    • - >(0.5-0= 0.5=>舍入为 1)如果有偶数个负数
    • 我们将此最终1/-1与实际结果的SUM-PRODUCT值进行多次对比

  • 任何领域都有大量的“使用空间”,例如金融领域,其增长率会随着时间的推移而复合。你可能有一只股票十年的日回报率,大约有 2500 个因子(周末不计算在内),都类似于 1.00043 和 0.99863,它们相乘得到累积的十年增长因子。标准中缺少 MULTIPLY 是一个重大缺陷。 (2认同)

Kon*_*rak 25

不,但你可以使用数学:)

如果yourColumn总是大于零:

select EXP(SUM(LOG(yourColumn))) As ColumnProduct from yourTable
Run Code Online (Sandbox Code Playgroud)


Rob*_*ijk 7

我看到Oracle的答案仍然缺失,所以这里是:

SQL> with yourTable as
  2  ( select 1 yourColumn from dual union all
  3    select 2 from dual union all
  4    select 4 from dual union all
  5    select 8 from dual
  6  )
  7  select EXP(SUM(LN(yourColumn))) As ColumnProduct from yourTable
  8  /

COLUMNPRODUCT
-------------
           64

1 row selected.
Run Code Online (Sandbox Code Playgroud)

问候,
Rob.