【发布时间】:2022-01-15 19:49:06
【问题描述】:
我正在尝试以面向性能的方式解决以下问题。我当前的实现涉及丑陋的循环,而且速度非常慢。
具体来说,我有一张表(交易),其中包含每个客户的各种商品的时间戳订单:
| timestamp | customer | item | volume |
|---|---|---|---|
| 2000 | Joe | A | 100 |
| 2001 | Joe | A | 200 |
| 2001 | Doe | A | 100 |
此外,我还有第二张表(估价)显示商品的价格:
| timestamp | item | price |
|---|---|---|
| 2000 | A | 1.1 |
| 2001 | A | 1.2 |
| 2002 | A | 1.3 |
现在,我想根据估值表中的时间戳跟踪每个客户的股票(累积数量)的价值(价格*股票):
| timestamp | customer | item | stock | value |
|---|---|---|---|---|
| 2000 | Joe | A | 100 | 110 |
| 2001 | Joe | A | 300 | 360 |
| 2002 | Joe | A | 300 | 390 |
| 2001 | Doe | A | 100 | 120 |
| 2002 | Doe | A | 100 | 130 |
本质上,这将是某种形式的(正确的)加入交易和估值。但是,这里的问题是我必须为每个(客户、项目)组合做一个正确的连接。换句话说,对于每个(客户、商品),我都必须加入完整的时间戳集。
我当前(可能非常低效)的解决方案在客户之间循环。对于每个客户,它会创建累积交易量、右连接估值和前向填充(使用最后一个函数)来自交易表的列:
CREATE OR REPLACE FUNCTION public.last_func(anyelement, anyelement)
RETURNS anyelement
LANGUAGE sql
IMMUTABLE STRICT
AS $function$
select $2;
$function$
;
create or replace function last_func(anyelement, anyelement)
returns anyelement language sql immutable strict
as $$
select $2;
$$;
select
valuations.timestamp,
last(t.customer) over (partition by valuations.item order by valuations.timestamp) as customer,
valuations.item,
last(t.stock) over (partition by valuations.item order by valuations.timestamp) as stock,
last(t.stock) over (partition by valuations.item order by valuations.timestamp) * valuations.price as value
from (select
timestamp,
customer,
item,
volume as order_volume,
sum(volume) over (partition by item order by item, timestamp) as stock
from
transactions
where customer = 'Joe') t
right join
valuations on t.timestamp = valuations.timestamp and t.item = valuations.item
这似乎相当低效,并且对于大量客户来说变得非常缓慢。有谁知道如何一次性做到这一点?如果你能在这里帮助我,那就太好了。
在此先感谢并致以最诚挚的问候
【问题讨论】:
-
请输入所需的输出
-
可以在第三个表中找到想要的输出
标签: sql postgresql