sql—获取日期组中的第一行,其中有一个不间断的日期序列

t1qtbnec  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(338)
  1. DECLARE @TestData TABLE (
  2. Idntty Int Not Null
  3. ,[DATE] DATE NOT NULL
  4. ,[TYPE] VARCHAR(20) NOT NULL
  5. )
  6. INSERT INTO @TestData VALUES
  7. (1, '2016-03-01', 'Inventory'),
  8. (2, '2016-04-01', 'Inventory'),
  9. (3, '2016-06-01', 'Inventory'),
  10. (4, '2016-07-01', 'Inventory'),
  11. (5, '2016-08-01', 'Inventory'),
  12. (6, '2016-09-01', 'Inventory'),
  13. (7, '2017-01-01', 'Inventory'),
  14. (8, '2017-02-01', 'Inventory'),
  15. (9, '2017-03-01', 'Inventory'),
  16. ;

基本上,我需要得到最后一组中的第一行,其中有一个没有中断的日期序列。
例如,此处的“2016-03-01”不正确,因为缺少“2016-05-01”,因此此日期记录的顺序存在中断。
分组的标准是连续日期,因此在示例中有3个分组,因为有2个中断,一个是因为缺少“2016-06-01”,第二个是因为缺少“2016-10-01”、“2016-11-01”、“2016-12-01”:

  1. (1, '2016-03-01', 'Inventory'),
  2. (2, '2016-04-01', 'Inventory'),
  3. and
  4. (3, '2016-06-01', 'Inventory'),
  5. (4, '2016-07-01', 'Inventory'),
  6. (5, '2016-08-01', 'Inventory'),
  7. (6, '2016-09-01', 'Inventory'),
  8. and
  9. (7, '2017-01-01', 'Inventory'),
  10. (8, '2017-02-01', 'Inventory'),
  11. (9, '2017-03-01', 'Inventory'),

所以我需要'2017-01-01'作为连续序列的第一个日期记录和最后一个序列的输出。
我尝试使用标准的缺口和孤岛解决方案,但没有取得任何成功,比如在这里应用什么。
我只想用sql来解决这个问题。我使用的是sql server 2008。

2q5ifsrm

2q5ifsrm1#

这确实是一个缺口和岛屿问题。基本上你想从最后一个岛开始。下面是一个使用窗口函数的选项:

  1. select max(date) res
  2. from (
  3. select t.*, lag(date) over(partition by type order by Idntty) lag_date
  4. from mytable t
  5. ) t
  6. where lag_date is null or date > dateadd(day, 1, lag_date)

在子查询中, lag() 提供“上一条”记录的日期。然后,外部查询筛选日期与上一条记录(即每个岛的开始日期)相差大于1天的行,并获取此结果集中的最大日期。

ttcibm8c

ttcibm8c2#

一种方法是使用循环。请尝试以下操作:

  1. DECLARE CUR CURSOR FAST_FORWARD FOR SELECT DISTINCT [DATE] FROM @TestData ORDER BY [DATE]
  2. DECLARE @DATE DATE
  3. DECLARE @PREV_DATE DATE = NULL, @FINAL_GRP_DATE DATE, @CN INT = -1
  4. OPEN CUR
  5. FETCH NEXT FROM CUR INTO @DATE
  6. WHILE (@@FETCH_STATUS = 0)
  7. BEGIN
  8. IF DATEDIFF(MM, @PREV_DATE, @DATE) = 1
  9. BEGIN
  10. SET @FINAL_GRP_DATE = @DATE
  11. SET @CN = -1
  12. END
  13. ELSE
  14. BEGIN
  15. SET @CN = 0
  16. END
  17. SET @PREV_DATE = @DATE
  18. FETCH NEXT FROM CUR INTO @DATE
  19. END
  20. CLOSE CUR
  21. DEALLOCATE CUR
  22. SELECT @FINAL_GRP_DATE

请在这里找到小提琴。

展开查看全部

相关问题