SQL-我如何使用 window 函数跨分区乘积/相乘
SQL-how can i product/ multiply across partitions with window functions
我的input由以下列组成:time
、UseID
和value
。我想将 plt
列作为连续数字的乘积。
我知道 SUM
window 函数可以对行求和,但是如何处理乘积?
time
UseID
value
plt
t1
116C123
a
a
t2
116C123
b
a*b
t3
116C123
c
a*b*c
t4
116C123
d
a*b*c*d
t2
116C111
a1
a1
t3
116C111
b1
a1*b1
t4
116C111
c1
a1*b1*c1
注意:输出应在实数域内
注意:此解决方案适用于 Postgres 数据库,不适用于 Redshift 数据库。我创建它是因为第一个 Postgres 在问题中被标记为 DB 类型。如果我应该删除答案,请告诉我。
假设您的示例数据的最后一行不正确(应该是 useid 116C111 而不是 116C123),您可以像这样进行乘法运算:
CREATE AGGREGATE MULTIPLICATE(int8) (SFUNC = int8mul, STYPE = int8);
然后在您的查询中使用它:
SELECT
time,
useid,
value,
MULTIPLICATE(value) OVER (PARTITION BY useid ORDER BY useid, value) AS plt
FROM input
GROUP BY useid, value, time
ORDER BY useid, value, time;
请在此处查看工作示例:db<>fiddle
如果您的示例数据确实正确,请描述其背后的逻辑。
您可以为此使用对数!
log(x) + log(y) = log(x*y) ==> x*y = exp(log(x) + log(y))
因此您的查询变为:
select
time,
UseID,
value,
exp(
sum(ln(value)) over (
partition by UseID
order by time asc
rows between unbounded preceding and current row
)
) as plt
from your_table
我的input由以下列组成:time
、UseID
和value
。我想将 plt
列作为连续数字的乘积。
我知道 SUM
window 函数可以对行求和,但是如何处理乘积?
time | UseID | value | plt |
---|---|---|---|
t1 | 116C123 | a | a |
t2 | 116C123 | b | a*b |
t3 | 116C123 | c | a*b*c |
t4 | 116C123 | d | a*b*c*d |
t2 | 116C111 | a1 | a1 |
t3 | 116C111 | b1 | a1*b1 |
t4 | 116C111 | c1 | a1*b1*c1 |
注意:输出应在实数域内
注意:此解决方案适用于 Postgres 数据库,不适用于 Redshift 数据库。我创建它是因为第一个 Postgres 在问题中被标记为 DB 类型。如果我应该删除答案,请告诉我。
假设您的示例数据的最后一行不正确(应该是 useid 116C111 而不是 116C123),您可以像这样进行乘法运算:
CREATE AGGREGATE MULTIPLICATE(int8) (SFUNC = int8mul, STYPE = int8);
然后在您的查询中使用它:
SELECT
time,
useid,
value,
MULTIPLICATE(value) OVER (PARTITION BY useid ORDER BY useid, value) AS plt
FROM input
GROUP BY useid, value, time
ORDER BY useid, value, time;
请在此处查看工作示例:db<>fiddle
如果您的示例数据确实正确,请描述其背后的逻辑。
您可以为此使用对数!
log(x) + log(y) = log(x*y) ==> x*y = exp(log(x) + log(y))
因此您的查询变为:
select
time,
UseID,
value,
exp(
sum(ln(value)) over (
partition by UseID
order by time asc
rows between unbounded preceding and current row
)
) as plt
from your_table