使用窗函数对连续数据进行分组

问题描述 投票:0回答:1

所以我有一个这样的数据库

ITEM   STOCK   DAY   
A      5       2024-08-12
B      2       2024-08-12
C      7       2024-08-12
A      3       2024-08-13
B      2       2024-08-13
C      7       2024-08-13
D      1       2024-08-13
A      3       2024-08-14
B      3       2024-08-15
C      7       2024-08-14
A      3       2024-08-15
B      3       2024-08-15
C      9       2024-08-15
A      2       2024-08-16
B      3       2024-08-16
C      7       2024-08-16
A      5       2024-08-17
B      2       2024-08-17
C      7       2024-08-17
D      3       2024-08-17

我想做的是使用窗口函数检查具有相同库存的商品的连续天数。

预期的结果会是这样的。 (连续的天数将写为CDAYS)

ITEM   CDAYS    DAY_START   DAY_END   
A      0        2024-08-12   2024-08-12
B      1        2024-08-12   2024-08-13  
C      5        2024-08-12   2024-08-17
A      2        2024-08-13   2024-08-15
D      0        2024-08-13   2024-08-13
B      2        2024-08-14   2024-08-16
A      0        2024-08-16   2024-08-16
A      0        2024-08-17   2024-08-17
B      0        2024-08-17   2024-08-17
D      0        2024-08-17   2024-08-17  

我尝试制作自己的窗口函数来解决这个问题,但失败了。

然而,我确实发现了问题所在。

像这样使用SQL

create table mytable (ITEM char, STOCK int,  DATE date);
insert into mytable values
('A',    5,    '2024-08-12'),
('B',    2,    '2024-08-12'),
('C',    7,    '2024-08-12'),
('A',    3,    '2024-08-13'),
('B',    2,    '2024-08-13'),
('C',    7,    '2024-08-13'),
('D',    1,    '2024-08-13'),
('A',    3,    '2024-08-14'),
('B',    3,    '2024-08-14'),
('C',    7,    '2024-08-14'),
('A',    3,    '2024-08-15'),
('B',    3,    '2024-08-15'),
('C',    7,    '2024-08-15'),
('A',    2,    '2024-08-16'),
('B',    3,    '2024-08-16'),
('C',    7,    '2024-08-16'),
('A',    5,    '2024-08-17'),
('B',    2,    '2024-08-17'),
('C',    7,    '2024-08-17'),
('D',    3,    '2024-08-17');


SELECT ITEM, STOCK,
ROW_NUMBER() OVER (PARTITION BY ITEM, STOCK ORDER BY DATE) AS Cdays, DATE
FROM mytable
ORDER BY ITEM, DATE

我得到如下结果

item    stock   cdays   date
A       5       1       2024-08-12
A       3       1       2024-08-13
A       3       2       2024-08-14
A       3       3       2024-08-15
A       2       1       2024-08-16
A       5       2       2024-08-17
B       2       1       2024-08-12
B       2       2       2024-08-13
B       3       1       2024-08-14
B       3       2       2024-08-15
B       3       3       2024-08-16
B       2       3       2024-08-17
C       7       1       2024-08-12
C       7       2       2024-08-13
C       7       3       2024-08-14
C       7       4       2024-08-15
C       7       5       2024-08-16
C       7       6       2024-08-17
D       1       1       2024-08-13
D       3       1       2024-08-17

查看项目 A,cdays 应该是 1 1 2 3 1 1,而不是 1 1 2 3 1 2。

如何修改我的 SQL,以便 2014 年 8 月 12 日和 2014 年 8 月 17 日的商品 A 库存不被视为连续数据?

sql sql-server window-functions
1个回答
0
投票

这是源自 Itzik Ben-Gan 的技术 1 的一种方法(我关于间隙和岛屿问题的首选文章):

WITH grps AS 
(
  SELECT ITEM, 
    STOCK,
    ROW_NUMBER() OVER (PARTITION BY ITEM ORDER BY DATE) -  
    ROW_NUMBER() OVER (PARTITION BY ITEM, STOCK ORDER BY DATE) AS grp,
    DATE
  FROM mytable
)
SELECT ITEM, STOCK, cdays = ROW_NUMBER() OVER 
       (PARTITION BY ITEM, grp, STOCK ORDER BY DATE), DATE
  FROM grps 
 ORDER BY ITEM, DATE;
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.