获取基于状态表的日期间隔

huangapple go评论123阅读模式
英文:

Get dates interval based on table of states

问题

promotion_product_id start_promotion_at end_promotion_at
1251589 2023-02-22 2023-03-07
1251589 2023-03-09 2023-03-10

英文:

I have a table that contains the states of whether a product was in promotion or not, along with the day of the state. The table looks like this:

day	        promotion_product_id   prev_order_promotion_product_id
2023-02-22  1251589	               1251589
2023-02-23  1251589	               1251589
2023-03-03  1251589	               1251589
2023-03-07  1251589	               1251589
2023-03-08  null                   1251589
2023-03-09  1251589	               null
2023-03-10  1251589	               1251589

What I want to get are the periods in which a certain product_id was in promotion. So for this case, the desired output would be:

promotion_product_id  start_promotion_at  end_promotion_at
1251589               2023-02-22          2023-03-07
1251589               2023-03-09          2023-03-10

I have been trying to use some windows function (max, min etc) but I am not even close to get the solution.

答案1

得分: 1

你可以使用窗口函数生成促销桶编号,然后按促销桶编号分组。

这是查询

with data_with_promotion_bucket AS 
(select
   dt,
   promotion_product_id,
   prev_order_promotion_product_id,
   sum(case 
       when promotion_product_id is not null 
       and promotion_product_id <> coalesce(prev_order_promotion_product_id,-1) 
       then 1 
       else 0 
       end
   ) over (order by dt) as promotion_bucket_number
from
   data_table
)
select
    max(promotion_product_id) as promotion_product_id,
    min(dt) as start_promotion_at,
    max(dt) as end_promotion_at  
from
    data_with_promotion_bucket
where
    promotion_product_id is not null
group by
    promotion_bucket_number
promotion_product_id start_promotion_at end_promotion_at
1251589 2023-02-22T00:00:00.000Z 2023-03-07T00:00:00.000Z
1251589 2023-03-09T00:00:00.000Z 2023-03-10T00:00:00.000Z
英文:

You can use window function to generate promotion_bucket_number and group by promotion_bucket_number

Here is the query:

with data_with_promotion_bucket AS 
(select
   dt,
   promotion_product_id,
   prev_order_promotion_product_id,
   sum(case 
       when promotion_product_id is not null 
       and promotion_product_id <> coalesce(prev_order_promotion_product_id,-1) 
       then 1 
       else 0 
       end
   ) over (order by dt) as promotion_bucket_number
from
   data_table
)
select
    max(promotion_product_id) as promotion_product_id,
    min(dt) as start_promotion_at,
    max(dt) as end_promotion_at  
from
    data_with_promotion_bucket
where
    promotion_product_id is not null
group by
    promotion_bucket_number
promotion_product_id start_promotion_at end_promotion_at
1251589 2023-02-22T00:00:00.000Z 2023-03-07T00:00:00.000Z
1251589 2023-03-09T00:00:00.000Z 2023-03-10T00:00:00.000Z

答案2

得分: 1

您可以使用以下查询。您必须使用您的表而不是临时表。

SELECT promotion_product_id, 
       MIN(day), 
       MAX(day)
FROM
(
    SELECT *, 
           SUM(IIF(promotion_product_id IS NULL, 1, 0)) OVER( PARTITION BY ISNULL(promotion_product_id, prev_promotion_product_id)
           ORDER BY day) AS grp
    FROM #temp
) AS t
WHERE promotion_product_id IS NOT NULL
GROUP BY promotion_product_id, 
         grp;
英文:

You can use query as below. You must use your table instead of temp table.

SELECT promotion_product_id, 
       MIN(day), 
       MAX(day)
FROM
(
    SELECT *, 
           SUM(IIF(promotion_product_id IS NULL, 1, 0)) OVER( partition by isnull(promotion_product_id,prev_promotion_product_id)
           ORDER BY day) grp
    FROM #temp
) AS t
WHERE promotion_product_id IS NOT NULL
GROUP BY promotion_product_id, 
         grp;

huangapple
  • 本文由 发表于 2023年3月7日 05:11:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/75655892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定