暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQL进阶的技巧:如何实现某列的累计乘积?

会飞的一十六 2024-09-18
178





01


场景描述


在做数据处理的时候,尤其是复利累积的时候,有时候会有这样一场景,通过某种条件找到一列数据[X1,X2,X3...Xn],然后想要求y=X1X2X3...Xn。下面给出一个具体案例来详细解释这一问题,如下图所示,每个组的name值只有2个(2个A/B/C),当name=A or C时,price为value字段的乘积,当name=B时候,price为vlaue字段的和。



02


数据准备






    create table multi_value as
    (


    select stack(
    13,
    'A',2,'甲',
    'B',5,'甲',
    'C',1,'甲',
    'B',7,'甲',
    'B',7,'甲',
    'A',1,'甲',
    'C',4,'甲',
    'A',5,'乙',
    'B',4,'乙',
    'C',6,'乙',
    'B',4,'乙',
    'A',3,'乙',
    'C',5,'乙'


    )as(name,value,org)


    );




    03


    问题分析

    本问题的难点在于求value列的累乘积,这个粗看时没有办法通过SQL实现的,因为SQL里面的分组汇总函数就那么几个sum,avg,max,min,count没有办法直接求一组数据连续相乘。经过仔细研究,我们可以利用数学中的对数恒等式及对数加法原理进行求解,公式如下:


    对数加法原理:

    log(MN)= log M + log N

    ln M*N = ln M + ln N

    对数恒等式:


    a^(LogaN)=N 


    e^(ln N) =N


     根据上述公式那么


     A*B = EXP(ln(A*B)) = EXP(lnA+lnB) = EXP(SUM(ln(FiledName)))


    A*B = POWER(10, SUM(LOG(10,FiledName)))


    即 A*B累计乘积就可以转换为对数运算+sum求和形式计算


    完整的SQL如下:

      select name
      , case
      when name in ('A', 'C') then ceil(exp(sum(ln(value))))
      when name in ('B') then sum(value) end price
      , org
      from multi_value
      group by org, name


      04


      小结


          本题主要利用数学中对数加法原理及对数恒等式进行求解,具有很强的技巧性,在实际分析中如复利累积场景中会遇到。





      文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论