Redshift 按时间将具有相同数据的分区分开

Redshift separate partitions with identical data by time

我在 Redshift table 中有数据,例如 product_id、价格和 time_of_purchase。我想为自上次购买以来每次价格变化创建分区。在这种情况下,一件商品的价格可能会回到以前的价格,但我需要将其作为一个单独的分区,例如:

注意价格是 2 美元,然后涨到 3 美元,然后又回到 2 美元。如果我做类似的事情(按 [=17= 分区],按 time_of_purchase 排序价格),那么最后一行将与前两行分区,这是我不想要的。我怎样才能正确地做到这一点,以便获得三个独立的分区?

lag()得到前一个值再求一个累加和:

select t.*,
       sum(case when prev_price = price then 0 else 1 end) over 
           (partition by product_id order by time_of_purchase) as partition_id
from (select t.*,
             lag(price) over (partition by product_id order by time_of_purchase) as prev_price
      from t
     ) t

与@Gordon Linoff 不同,我更喜欢使用 WITH 子句一步步完成...

并且,正如我在其他 post 中多次提到的那样 - 请以 copy-paste 就绪格式添加您的示范数据,这样我们就不必 copy-paste 您的示例.

我喜欢以self-contained微型演示格式添加我的示例,输入数据已经在我的post中,这样每个人都可以玩它,这就是为什么..

WITH
-- your input, typed manually ....
indata(product_id,price,tm_of_p) AS (
          SELECT 1,2.00,TIMESTAMP '2020-09-14 09:00'
UNION ALL SELECT 1,2.00,TIMESTAMP '2020-09-14 10:00'
UNION ALL SELECT 1,3.00,TIMESTAMP '2020-09-14 11:00'
UNION ALL SELECT 1,3.00,TIMESTAMP '2020-09-14 12:00'
UNION ALL SELECT 1,2.00,TIMESTAMP '2020-09-14 13:00'
)
,
with_change_counter AS (
  SELECT
    *
  , CASE WHEN LAG(price) OVER(PARTITION BY product_id ORDER BY tm_of_p) <> price
     THEN 1
     ELSE 0
    END AS chg_count
  FROM indata
)
SELECT
  product_id
, price
, tm_of_p
, SUM(chg_count) OVER(PARTITION BY product_id ORDER BY tm_of_p) AS session_id
FROM with_change_counter;
-- out  product_id | price |       tm_of_p       | session_id 
-- out ------------+-------+---------------------+------------
-- out           1 |  2.00 | 2020-09-14 09:00:00 |          0
-- out           1 |  2.00 | 2020-09-14 10:00:00 |          0
-- out           1 |  3.00 | 2020-09-14 11:00:00 |          1
-- out           1 |  3.00 | 2020-09-14 12:00:00 |          1
-- out           1 |  2.00 | 2020-09-14 13:00:00 |          2