创建日期范围

时间:2018-11-29 12:13:53

标签: sql tsql sql-server-2016 date-range gaps-and-islands

我正在尝试根据某些条件生成日期范围。

我的数据包含供应商,供应商,价格和价格。我想创建1行来显示供应商,upc,价格点,开始日期,结束日期,只要在任何给定供应商,upc,价格点的1个邀请和下一个之间的间隔少于4天。

我们最近才迁移到SQL Server 2016,但我不确定实现此目的的最佳/最简便方法。

sample

谢谢。

结果应为:

183020   2840000211 1.47  12/23/16 - 12/26/16
183020   2840000211 1.39  12/31/16 - 01/03/17
183020   2840000211 1.39  01/09/17 - 01/16/17

2 个答案:

答案 0 :(得分:1)

这是一个完美的场景,其中所需输出中的每个记录都代表一个孤岛(其中net_cost不变,并且您有inv_date个快照在确认后不到4天确认了它)前一个)。差距是未表示的net_cost / inv_date值(例如,我们不知道{{1}到net_cost的{​​{1}}上的inv_date是什么}}。

下面的查询执行三件事:

  1. 通过检查是否存在间隙(列2016-12-27)来确定 违反了问题中提出的2个约束条件( 2016-12-30is_gap_start值有4天或更长时间的间隔)
  2. 使用碰到的间隔的总计来分配岛号(列net_cost)。
  3. 确定要在最终结果中显示的每个岛屿的值

答案:

inv_date

结果:

island_nbr

答案 1 :(得分:0)

这是我想出的,并不能完全解决您的问题,但是我觉得我可以发布这段代码,至少让您完成其余工作,并可能找到一个可以解决的答案(记住我的评论)

DECLARE @TableVar TABLE 
  ( 
     vnd_nbr  INT, 
     upc_nbr  VARCHAR(10), 
     inv_date DATE, 
     net_cost DECIMAL(16, 2) 
  ) 

INSERT INTO @TableVar 
            (vnd_nbr, 
             upc_nbr, 
             inv_date, 
             net_cost) 
VALUES      (183020, 
             '2840000211', 
             '23-Dec-2016', 
             1.47), 
            (183020, 
             '2840000211', 
             '26-Dec-2016', 
             1.47), 
            (183020, 
             '2840000211', 
             '31-Dec-2016', 
             1.39), 
            (183020, 
             '2840000211', 
             '2-Jan-2017', 
             1.39), 
            (183020, 
             '2840000211', 
             '3-Jan-2017', 
             1.39), 
            (183020, 
             '2840000211', 
             '09-Jan-2017', 
             1.39), 
            (183020, 
             '2840000211', 
             '12-Jan-2017', 
             1.39), 
            (183020, 
             '2840000211', 
             '13-Jan-2017', 
             1.39), 
            (183020, 
             '2840000211', 
             '14-Jan-2017', 
             1.39), 
            (183020, 
             '2840000211', 
             '16-Jan-2017', 
             1.39) 

SELECT vnd_nbr, 
       upc_nbr, 
       net_cost, 
       Min(Isnull(previous_date, inv_date)) AS StartDate, 
       Max(inv_date)                        AS EndDate 
FROM   (SELECT vnd_nbr, 
               upc_nbr, 
               inv_date, 
               net_cost, 
               previous_date, 
               CASE 
                 WHEN Datediff(day, Isnull(previous_date, inv_date), inv_date) < 
                      4 THEN 
                 0 
                 ELSE 1 
               END GreaterThanFourDays 
        FROM   (SELECT vnd_nbr, 
                       upc_nbr, 
                       inv_date, 
                       net_cost, 
                       Lag(inv_date, 1, NULL) 
                         OVER ( 
                           partition BY vnd_nbr, upc_nbr, net_cost 
                           ORDER BY inv_date) AS previous_date 
                FROM   @TableVar) r) rr 
GROUP  BY greaterthanfourdays, 
          vnd_nbr, 
          upc_nbr, 
          net_cost 
ORDER  BY Min(inv_date) 

以上输出此:

vnd_nbr upc_nbr net_cost    StartDate   EndDate
183020  2840000211  1.47    2016-12-23  2016-12-26
183020  2840000211  1.39    2016-12-31  2017-01-16
183020  2840000211  1.39    2017-01-03  2017-01-09

开始/结束日期不匹配,但是如果超过4天/考虑了net_cost,则会将其拆分。

就像我说的那样,它不能完全解决您的问题,但是可以使您了解如何做自己想做的事情。

相关问题