Sql 按时间红移具有相同数据的独立分区

Sql 按时间红移具有相同数据的独立分区,sql,amazon-redshift,partition,Sql,Amazon Redshift,Partition,我在红移表中有数据,如产品id、价格和购买时间。我想为自上次购买以来的每次价格变化创建分区。在这种情况下,一个项目的价格可能会回到以前的价格,但我需要它是一个单独的分区,例如: 注意价格是2美元,然后上升到3美元,然后又回到2美元。如果我做一些类似于按产品id划分、按购买时间划分价格订单的事情,那么最后一行将与前两行进行划分,这是我不想要的。如何正确执行此操作以获得三个单独的分区?使用lag获得上一个值,然后是一个累积和: select t.*, sum(case when pre

我在红移表中有数据,如产品id、价格和购买时间。我想为自上次购买以来的每次价格变化创建分区。在这种情况下,一个项目的价格可能会回到以前的价格,但我需要它是一个单独的分区,例如:

注意价格是2美元,然后上升到3美元,然后又回到2美元。如果我做一些类似于按产品id划分、按购买时间划分价格订单的事情,那么最后一行将与前两行进行划分,这是我不想要的。如何正确执行此操作以获得三个单独的分区?

使用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
使用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子句

而且,正如我在其他帖子中多次指出的,请以复制粘贴就绪的格式添加您的示例数据,这样我们就不必复制粘贴您的示例

我喜欢以一种自我包含的微演示格式添加我的示例,输入数据已经在我的帖子中,所以每个人都可以使用它,这就是为什么

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

与@Gordon Linoff相反,我更喜欢一步一步地做,使用WITH子句

而且,正如我在其他帖子中多次指出的,请以复制粘贴就绪的格式添加您的示例数据,这样我们就不必复制粘贴您的示例

我喜欢以一种自我包含的微演示格式添加我的示例,输入数据已经在我的帖子中,所以每个人都可以使用它,这就是为什么

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

很酷,戈登·林诺夫!基于价格变化的会话…谢谢!我需要在分区id的定义中添加一个框架子句,所以在购买的…按时间订购之后,我需要在无界的前一行和当前行之间的行,但除此之外,你的想法成功了。酷一点,@Gordon Linoff!基于价格变化的会话…谢谢!我需要在分区id的定义中添加一个框架子句,所以在按购买时间排序之后,我需要在无界的前一行和当前行之间添加行,但除此之外,您的想法起到了作用。