我有一个大数据集(100多万行),我需要根据start_date和end_date之间的月数分成行,以便进行会计。
所以例如这条记录应分成3612行,因为在start_date和end_date之间有3612个月:
我所追求的结果应如下所示:
我知道我可以使用递归CTE来实现这一点,但是对于这么大的数据集需要FOREVER。有没有更有效的方法呢?
答案 0 :(得分:3)
在此查询中,我使用master.dbo.spt_values
作为计数表。但它不适合你,因为它只有2048年的数字。所以你必须创建自己的数字表并在查询中用它更改master.dbo.spt_values
。
declare @t table (
id int
, start_date date
, end_date date
, months int
)
insert into @t
values (1, '19990101', '21000101', 1212)
select
t.id, month_num = v.number + 1
, total_days = sum(datediff(dd, dateadd(mm, v.number, t.start_date), dateadd(mm, v.number + 1, t.start_date))) over (partition by t.id)
, t.start_date, t.end_date
from
@t t
join master.dbo.spt_values v on t.months > v.number
where
v.type = 'P'
答案 1 :(得分:0)
declare @numbers TABLE (ID int NOT NULL primary key);
INSERT INTO @numbers (ID)
VALUES
(1)
,(2)
,(3)
,(4)
,(5)
,(6)
,(7)
,(8);
declare @range TABLE (cnt int);
INSERT INTO @range (cnt)
VALUES (1), (4), (6);
select r.cnt, n.ID
from @range r
join @numbers n
on n.ID < = r.cnt
order by r.cnt, n.ID;
答案 2 :(得分:0)
我不得不在不到一周前做同样的事情!
-----DLL
CREATE TABLE Reporting_Table (
Credit_Line_NO Varchar(10),
noMonths INT,
EFFECTIVEDATE Date,
EXPIRY_DATE Date,
Amount Money,
mxDays INT,
mxFactor decimal(5,4),
Calc Money)
INSERT INTO Reporting_Table (Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc)
Values('9938810','3','3/31/2018','6/12/2020','11718.75','90','1','11718.75')
INSERT INTO Reporting_Table (Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc)
Values('2235461','1','6/30/2018','6/6/2019','12345','30','1','12345')
INSERT INTO Reporting_Table (Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc)
Values('3365434','12','6/30/2018','6/30/2019','298523.36085','365','1.01388888888889','302669.518639583')
---- VIEW DATA SET . . .
Select *, (DATEDIFF(MONTH,EFFECTIVEDATE,EXPIRY_DATE)/noMonths)+1 as FREQ
From Reporting_Table
- 现在你有一个可以摆弄的工作数据集,只需展开所有相关的拖链。
;with cte as
(
select Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc,
(DATEDIFF(MONTH,EFFECTIVEDATE,EXPIRY_DATE)/noMonths)+1 as FREQ,
1 as Rec_Iteration
from Reporting_Table
where noMonths > 1
union all
select Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc,
(DATEDIFF(MONTH,EFFECTIVEDATE,EXPIRY_DATE)/noMonths)+1 as FREQ,
Rec_Iteration + 1
from cte
where Rec_Iteration < FREQ
)
select Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc,
(DATEDIFF(MONTH,EFFECTIVEDATE,EXPIRY_DATE)/noMonths)+1 as FREQ
from cte
order by Credit_Line_NO,
Rec_Iteration