如何将日期范围 table 转换为基于行的视图?
How to convert a date range table to a row based view?
我面临着一个艰难的处境。到目前为止我找不到解决方案。
我有一个 table 根据日期范围提供信息。我想按日期细分这些信息。所以我希望将范围转换为行结构。
额外的困难是日期范围内的“期间”数量是可变的。
"periodicity" 减去日期范围和一个周期的天数。
更具体地说,在 table 的一行中,我有一个
- ID
- start_date of the range
- end_date of the range
- number of days_in_the_period
- numbers_periods
- pricings to apply to each period in the range
这是初始 table 结构和预期结果:
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
有关信息,初始 table 包含大约 10 万条记录。
有人对我有绝妙的主意吗?
请回复以进行任何说明,
塔尔蒂诺
您可以在递归 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]
另一种方法是使用日历 table,并将其与您的 table 相结合。
我面临着一个艰难的处境。到目前为止我找不到解决方案。
我有一个 table 根据日期范围提供信息。我想按日期细分这些信息。所以我希望将范围转换为行结构。
额外的困难是日期范围内的“期间”数量是可变的。 "periodicity" 减去日期范围和一个周期的天数。
更具体地说,在 table 的一行中,我有一个
- ID
- start_date of the range
- end_date of the range
- number of days_in_the_period
- numbers_periods
- pricings to apply to each period in the range
这是初始 table 结构和预期结果:
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
有关信息,初始 table 包含大约 10 万条记录。 有人对我有绝妙的主意吗?
请回复以进行任何说明, 塔尔蒂诺
您可以在递归 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]
另一种方法是使用日历 table,并将其与您的 table 相结合。