我有一个帐户列表及其费用,每隔几天就会更改一次。 在此列表中,每次成本更新为新结果时,我只有开始日期,但结束日期没有列。 这意味着,我需要填写特定帐户和费用的结束日期的日期列表,并将其推断为具有新费用的同一帐户的开始日期。
或多或少那样:
帐户开始日期费用
一个1/1/2016 100 $
两个1/1/2016 150 $
一个4/1/2016 200 $
两个3/1/2016 200 $
我需要的结果是:
帐户日期费用
一个1/1/2016 100 $
一个2/1/2016 100 $
一个3/1/2016 100 $
一个4/1/2016 200 $
两个1/1/2016 150 $
两个2/1/2016 150 $
两个3/1/2016 200 $
例如,如果成本在月中更改,则样本数据将只保留两条记录(每个唯一的帐户开始日期成本组合一条),而结果将保留30条记录每月的每一天的费用(第一笔费用为15英镑,第二笔费用为15英镑)。成本是给定的,无需计算(手动插入)。
请注意,结果包含更多记录,因为样本数据仅显示该帐户的开始日期和更新费用。虽然结果显示了每月的每一天的成本。
有什么想法吗?
答案 0 :(得分:1)
解决方案有点长。
我为测试目的添加了额外的日期:
DECLARE @t table(account varchar(10), startdate date, cost int)
INSERT @t
values
('one','1/1/2016',100),('two','1/1/2016',150),
('one','1/4/2016',200),('two','1/3/2016',200),
('two','1/6/2016',500) -- extra row
;WITH CTE as
( SELECT
row_number() over (partition by account order by startdate) rn,
*
FROM @t
),N(N)AS
(
SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)
),
tally(N) AS -- tally is limited to 1000 days
(
SELECT ROW_NUMBER()OVER(ORDER BY N.N) - 1 FROM N,N a,N b
),GROUPED as
(
SELECT
cte.account, cte.startdate, cte.cost, cte2.cost cost2, cte2.startdate enddate
FROM CTE
JOIN CTE CTE2
ON CTE.account = CTE2.account
and CTE.rn = CTE2.rn - 1
)
-- used DISTINCT to avoid overlapping dates
SELECT DISTINCT
CASE WHEN datediff(d, startdate,enddate) = N THEN cost2 ELSE cost END cost,
dateadd(d, N, startdate) startdate,
account
FROM grouped
JOIN tally
ON datediff(d, startdate,enddate) >= N
结果:
cost startdate account
100 2016-01-01 one
100 2016-01-02 one
100 2016-01-03 one
150 2016-01-01 two
150 2016-01-02 two
200 2016-01-03 two
200 2016-01-04 one
200 2016-01-04 two
200 2016-01-05 two
500 2016-01-06 two
答案 1 :(得分:0)
谢谢@ t-clausen.dk!
它没有完全解决问题,但确实以正确的方式指导我。
最后,我使用LEAD函数为每个帐户的每个费用生成结束日期,然后我可以根据that idea填充日期列表。
以下是我如何生成结束日期:
DECLARE @t table(account varchar(10), startdate date, cost int)
INSERT @t
values
('one','1/1/2016',100),('two','1/1/2016',150),
('one','1/4/2016',200),('two','1/3/2016',200),
('two','1/6/2016',500)
select account
,[startdate]
,DATEADD(DAY, -1, LEAD([Startdate], 1,'2100-01-01') OVER (PARTITION BY account ORDER BY [Startdate] ASC)) AS enddate
,cost
from @t
它返回了预期的结果:
帐户启动日期结束日期
一2016-01-01 2016-01-03 100
一2016-01-04 2099-12-31 200
二2016-01-01 2016-01-02 150
二2016-01-03 2016-01-05 200
二2016-01-06 2099-12-31 500
请注意,我将当前费用的结束日期设置为远期的某个日期,这意味着(对我来说)他们当前处于活动状态。