如何根据连续的日期范围对数据进行分组?

How to group data based on continuous date range?

我正在尝试根据日期和价格对以下样本数据进行分组。

PRODUCT_CODE PRICING_DATE PRICE
1234 01-01-2022 23.9
1234 02-01-2022 23.9
1234 03-01-2022 23.9
1234 04-01-2022 22.9
1234 05-01-2022 22.9
1234 06-01-2022 24.9
1234 07-01-2022 24.9
1234 08-01-2022 23.9
1234 09-01-2022 23.9

期望的输出:

PRODUCT_CODE MIN_DATE MAX_DATE PRICE
1234 01-01-2022 03-01-2022 23.9
1234 04-01-2022 05-01-2022 22.9
1234 06-01-2022 07-01-2022 24.9
1234 08-01-2022 09-01-2022 23.9

我试过这个查询,但它没有给出正确的输出。

SELECT Product_Code,
    min(Pricing_Date) AS Min_Date,
    max(Pricing_Date) AS Max_Date, 
    price 
FROm PRICE_DATA
GROUP BY
    Product_Code,
    Price

输出

PRODUCT_CODE MIN_DATE MAX_DATE PRICE
1234 01-01-2022 09-01-2022 23.9
1234 04-01-2022 05-01-2022 22.9
1234 06-01-2022 07-01-2022 24.9

所以价格的日期范围是 23.9 是不正确的,因为该范围内所有日期的价格都不相同。我不确定如何根据需要的输出对数据进行分区。

基本上我不想要任何重叠的日期范围。

数据库:SQL 服务器 13

the date range for price is 23.9 is not right because price not same for all the days in that range.

因为在不同的重叠日期范围内有两个相同的price,所以当您使用聚合函数时,您可能只得到一行。

这是一个gap-and-island的问题,我们可以尝试使用ROW_NUMBERwindow函数来获取重叠日期的差距,然后group by

SELECT  Product_Code,
        min(Pricing_Date) AS Min_Date ,
        max(Pricing_Date) AS Max_Date, 
        price
FROM (
    SELECT *,
           ROW_NUMBER() OVER(ORDER BY PRICING_DATE) - ROW_NUMBER() OVER(PARTITION BY  PRODUCT_CODE,PRICE ORDER  BY PRICING_DATE) grp
    FROM PRICE_DATA 
) t1
GROUP BY grp,Product_Code,price
ORDER BY  min(Pricing_Date)

sqlfiddle

解释

gap-and-island 问题是一个特征

continuous(overlapping) data is that a set (continuous range of sequence) - (values ​​based on a certain order of conditions sequence) yields the same grouping.

这样我们就可以使用

  • ROW_NUMBER() OVER(ORDER BY PRICING_DATE) 制作一个连续的值范围。
  • ROW_NUMBER() OVER(PARTITION BY PRODUCT_CODE,PRICE ORDER BY PRICING_DATE)根据一定的条件顺序取值

然后我们将得到一个包含重叠数据的分组列 sqlfiddle