【问题标题】:How to convert a date range table to a row based view?如何将日期范围表转换为基于行的视图?
【发布时间】:2016-09-26 13:52:41
【问题描述】:

我正面临艰难的处境。到目前为止我找不到解决方案。

我有一个根据日期范围提供信息的表格。我想按日期细分这些信息。所以我希望将范围转换为行结构。

额外的困难是日期范围内的“句点”数量是可变的。 “周期”是从日期范围和一个周期的天数中扣除的。

更具体地说,在表格的一行我有一个

  • 身份证
  • 范围的开始日期
  • 范围的结束日期
  • _in_the_period 天数
  • numbers_periods
  • 适用于该范围内每个时期的定价

这是初始表结构和预期结果:

CREATE TABLE Start(
 Key                VARCHAR(11) NOT NULL PRIMARY KEY
,Start_date         VARCHAR(27) NOT NULL
,End_Date           VARCHAR(27) NOT NULL
,Days_in_the_period INTEGER  NOT NULL
,Nbr_periods        INTEGER  NOT NULL
,Pricing            VARCHAR(6) NOT NULL
);
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2000-06-01 00:00:00.0000000','2001-12-01 00:00:00.0000000',30,19,'800,87');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2002-01-01 00:00:00.0000000','2005-12-01 00:00:00.0000000',30,48,'440,32');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2006-01-01 00:00:00.0000000','2007-02-01 00:00:00.0000000',30,14,'282,68');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2007-03-01 00:00:00.0000000','2008-03-01 00:00:00.0000000',30,13,'283,99');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2008-04-01 00:00:00.0000000','2009-01-01 00:00:00.0000000',60,5,'281,81');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2009-02-01 00:00:00.0000000','2009-03-01 00:00:00.0000000',30,2,'281,81');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2009-04-01 00:00:00.0000000','2019-07-01 00:00:00.0000000',30,124,'281,81');
INSERT INTO Start(Key,Start_date,End_Date,Days_in_the_period,Nbr_periods,Pricing) VALUES ('010-1280001','2019-08-01 00:00:00.0000000','2019-08-01 00:00:00.0000000',0,1,'372,96');

预期

  Key                  Date               Pricing   Days_in_the_period  

010-1280001 2000-06-01 00:00:00.0000000 800,87 30
010-1280001 2000-07-01 00:00:00.0000000 800,87 30
………………
010-1280001 2008-04-01 00:00:00.0000000 281,81 60
010-1280001 2008-06-01 00:00:00.0000000 281,81 60
………………
010-1280001 2019-08-01 00:00:00.0000000 372,96 0

关于信息,初始表包含大约 100k 条记录。 有人对我有一个绝妙的主意吗?

请回复任何澄清, 塔蒂诺。

【问题讨论】:

  • 这是一个很好的起点。 spaghettidba.com/2015/04/24/…
  • 你能解释一下开始和结束日期如何成为预期结果中的单个日期列的逻辑吗?
  • 亲爱的 Kannan, 范围的开始日期成为单个日期中的第一个日期。然后根据期间的天数,计算出第二个单日。 (30 天将四舍五入为一个月)它会持续多少次(或直到结束日期)

标签: sql-server type-conversion date-range management-studio-express


【解决方案1】:

您可以在递归 CTE 的帮助下做到这一点:

;WITH cte AS (
    SELECT  *
    FROM YourTable
    UNION ALL
    SELECT  c.[key],
            DATEADD(month,c.Days_in_the_period/30,c.[Start_Date]),
            c.End_Date,
            c.Days_in_the_period,
            c.Nbr_periods,
            c.Pricing
    FROM cte c
    INNER JOIN YourTable y
        ON y.[key] = c.[key] AND c.End_Date = y.End_Date
    WHERE y.End_Date >=DATEADD(month,c.Days_in_the_period/30,c.[Start_Date])
)


SELECT  [key],
        [Start_Date] as [Date],
        Pricing,
        Days_in_the_period
FROM cte
ORDER BY [key], [Start_Date]

另一种方法是使用日历表,并将其与您的表连接起来。

【讨论】:

  • 谢谢Gofr,你的结构派上用场了。我不得不更改一些小东西以避免无限递归,但它现在工作正常。
  • 此代码适用于您提供的数据样本(我使用了前两行)。如果间隔超过 100 天,请使用 OPTION (MAXRECURSION 0) - 忘了在我的回答中提及。
  • 很高兴听到这个消息!如果我的回答对您有帮助,欢迎接受/点赞!
  • 最后一行的天数为 0,并且会从 0/30 + any = any 开始在无限循环中生成。但这只是一个细节。谢谢!!
猜你喜欢
  • 2013-11-05
  • 1970-01-01
  • 2021-04-18
  • 2020-12-08
  • 2021-07-20
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
  • 2016-12-10
相关资源
最近更新 更多