当当前行为 null 时使用最后一个值,对于 PostgreSQL 时间序列 table
Use last value when current row is null , for PostgreSQL timeseries table
我遇到一个问题,我找不到最佳解决方案。所以我的想法是在每个给定时间从商店列表中获取产品列表的价格,但是因为价格是在不同时间注册的,所以我在按时间分组时得到一些空值,还有一个数组 o 值。因此,它需要几个步骤才能获得我需要的东西。我想知道是否有人知道更好、更快的方法来实现这一目标。 Bellow 是我最初的 PostgreSQL table 当然这只是其中的一个片段来理解这个想法:
初始Table
期望的结果(中间 table 和最后一个)
下面是 PostgreSQL sql 代码,它给出了我想要的结果,但它似乎非常昂贵:
SELECT times,
first_value(price_yami_egg) OVER (PARTITION BY partition_price_yami_egg order by time) as price_yami_egg
first_value(price_yami_salt) OVER (PARTITION BY partition_price_yami_salt order by time) as price_yami_salt
first_value(price_dobl_egg) OVER (PARTITION BY partition_price_dobl_egg order by time) as price_dobl_egg
first_value(price_dobl_salt) OVER (PARTITION BY partition_price_dobl_salt order by time) as price_dobl_salt
FROM(
SELECT time,
min(price_yami_egg) as price_yami_egg,
sum(case when min(price_yami_egg) is not null then 1 end) over (order by times) as partition_price_yami_egg
min(price_yami_salt) as price_yami_salt,
sum(case when min(price_yami_salt) is not null then 1 end) over (order by times) as partition_price_yami_salt
min(price_dobl_egg) as price_dobl_egg,
sum(case when min(price_dobl_egg) is not null then 1 end) over (order by times) as partition_price_dobl_egg
min(price_dobl_salt) as price_dobl_salt,
sum(case when min(price_dobl_salt) is not null then 1 end) over (order by times) as partition_price_dobl_salt
FROM (
SELECT "time" AS times,
CASE WHEN shop_name::text = 'yami'::text AND product_name::text = 'egg'::text THEN price END AS price_yami_egg
CASE WHEN shop_name::text = 'yami'::text AND product_name::text = 'salt'::text THEN price END AS price_yami_salt
CASE WHEN shop_name::text = 'dobl'::text AND product_name::text = 'egg'::text THEN price END AS price_dobl_egg
CASE WHEN shop_name::text = 'dobl'::text AND product_name::text = 'salt'::text THEN price END AS price_dobl_salt
FROM shop sh
) S
GROUP BY time
ORDER BY time) SS
你只是想要聚合吗?
select time,
min(price) filter (where shop_name = 'Yami' and product_name = 'EGG'),
min(price) filter (where shop_name = 'Yami' and product_name = 'SALT'),
min(price) filter (where shop_name = 'Dobl' and product_name = 'EGG'),
min(price) filter (where shop_name = 'Dobl' and product_name = 'SALT')
from shop s
group by time;
如果。你关心的是结果中的 NULL
值,然后你可以填写它们。这有点棘手,但想法是:
with t as (
select time,
min(price) filter (where shop_name = 'Yami' and product_name = 'EGG') as yami_egg,
min(price) filter (where shop_name = 'Yami' and product_name = 'SALT') as yami_salt,
min(price) filter (where shop_name = 'Dobl' and product_name = 'EGG') as dobl_egg,
min(price) filter (where shop_name = 'Dobl' and product_name = 'SALT') as dobl_salt
from shop s
group by time
)
select s.*,
max(yaml_egg) over (yaml_egg_grp) as imputed_yaml_egg,
max(yaml_salt) over (yaml_egg_grp) as imputed_yaml_salt,
max(dobl_egg) over (yaml_egg_grp) as imputed_dobl_egg,
max(dobl_salt) over (yaml_egg_grp) as imputed_dobl_salt
from (select s.*,
count(yaml_egg) over (order by time) as yaml_egg_grp,
count(yaml_salt) over (order by time) as yaml_egg_grp,
count(dobl_egg) over (order by time) as dobl_egg_grp,
count(dobl_salt) over (order by time) as dobl_salt_grp
from s
) s
我遇到一个问题,我找不到最佳解决方案。所以我的想法是在每个给定时间从商店列表中获取产品列表的价格,但是因为价格是在不同时间注册的,所以我在按时间分组时得到一些空值,还有一个数组 o 值。因此,它需要几个步骤才能获得我需要的东西。我想知道是否有人知道更好、更快的方法来实现这一目标。 Bellow 是我最初的 PostgreSQL table 当然这只是其中的一个片段来理解这个想法:
初始Table
期望的结果(中间 table 和最后一个)
下面是 PostgreSQL sql 代码,它给出了我想要的结果,但它似乎非常昂贵:
SELECT times,
first_value(price_yami_egg) OVER (PARTITION BY partition_price_yami_egg order by time) as price_yami_egg
first_value(price_yami_salt) OVER (PARTITION BY partition_price_yami_salt order by time) as price_yami_salt
first_value(price_dobl_egg) OVER (PARTITION BY partition_price_dobl_egg order by time) as price_dobl_egg
first_value(price_dobl_salt) OVER (PARTITION BY partition_price_dobl_salt order by time) as price_dobl_salt
FROM(
SELECT time,
min(price_yami_egg) as price_yami_egg,
sum(case when min(price_yami_egg) is not null then 1 end) over (order by times) as partition_price_yami_egg
min(price_yami_salt) as price_yami_salt,
sum(case when min(price_yami_salt) is not null then 1 end) over (order by times) as partition_price_yami_salt
min(price_dobl_egg) as price_dobl_egg,
sum(case when min(price_dobl_egg) is not null then 1 end) over (order by times) as partition_price_dobl_egg
min(price_dobl_salt) as price_dobl_salt,
sum(case when min(price_dobl_salt) is not null then 1 end) over (order by times) as partition_price_dobl_salt
FROM (
SELECT "time" AS times,
CASE WHEN shop_name::text = 'yami'::text AND product_name::text = 'egg'::text THEN price END AS price_yami_egg
CASE WHEN shop_name::text = 'yami'::text AND product_name::text = 'salt'::text THEN price END AS price_yami_salt
CASE WHEN shop_name::text = 'dobl'::text AND product_name::text = 'egg'::text THEN price END AS price_dobl_egg
CASE WHEN shop_name::text = 'dobl'::text AND product_name::text = 'salt'::text THEN price END AS price_dobl_salt
FROM shop sh
) S
GROUP BY time
ORDER BY time) SS
你只是想要聚合吗?
select time,
min(price) filter (where shop_name = 'Yami' and product_name = 'EGG'),
min(price) filter (where shop_name = 'Yami' and product_name = 'SALT'),
min(price) filter (where shop_name = 'Dobl' and product_name = 'EGG'),
min(price) filter (where shop_name = 'Dobl' and product_name = 'SALT')
from shop s
group by time;
如果。你关心的是结果中的 NULL
值,然后你可以填写它们。这有点棘手,但想法是:
with t as (
select time,
min(price) filter (where shop_name = 'Yami' and product_name = 'EGG') as yami_egg,
min(price) filter (where shop_name = 'Yami' and product_name = 'SALT') as yami_salt,
min(price) filter (where shop_name = 'Dobl' and product_name = 'EGG') as dobl_egg,
min(price) filter (where shop_name = 'Dobl' and product_name = 'SALT') as dobl_salt
from shop s
group by time
)
select s.*,
max(yaml_egg) over (yaml_egg_grp) as imputed_yaml_egg,
max(yaml_salt) over (yaml_egg_grp) as imputed_yaml_salt,
max(dobl_egg) over (yaml_egg_grp) as imputed_dobl_egg,
max(dobl_salt) over (yaml_egg_grp) as imputed_dobl_salt
from (select s.*,
count(yaml_egg) over (order by time) as yaml_egg_grp,
count(yaml_salt) over (order by time) as yaml_egg_grp,
count(dobl_egg) over (order by time) as dobl_egg_grp,
count(dobl_salt) over (order by time) as dobl_salt_grp
from s
) s