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没有办法直接求一组数据连续相乘。经过仔细研究,我们可以利用数学中的对数恒等式及对数加法原理进行求解,公式如下:
对数加法原理:
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, casewhen name in ('A', 'C') then ceil(exp(sum(ln(value))))when name in ('B') then sum(value) end price, orgfrom multi_valuegroup by org, name

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

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




