Sql 需要存储过程来查找缺少的间隙并插入行
我这里有一个小的开发挑战。我在SQL Server中有下表<代码>当前费率代码>:Sql 需要存储过程来查找缺少的间隙并插入行,sql,sql-server,tsql,Sql,Sql Server,Tsql,我这里有一个小的开发挑战。我在SQL Server中有下表当前费率: SELECT * FROM (VALUES (1001300, 'USD', 13, '8/1/2013', 1.31), (1001301, 'USD', 13, '8/2/2013', 1.32), (1001302, 'USD', 13, '8/5/2013', 1.33), (1001303, 'USD', 13, '8/6/2013', 1.34), (1001304, 'USD', 13, '8/7/2013',
SELECT *
FROM (VALUES
(1001300, 'USD', 13, '8/1/2013', 1.31),
(1001301, 'USD', 13, '8/2/2013', 1.32),
(1001302, 'USD', 13, '8/5/2013', 1.33),
(1001303, 'USD', 13, '8/6/2013', 1.34),
(1001304, 'USD', 13, '8/7/2013', 1.35),
(1001305, 'USD', 13, '8/8/2014', 1.31),
(1001306, 'USD', 13, '8/9/2013', 1.32),
(1001307, 'USD', 13, '8/12/2013', 1.33),
(1001308, 'USD', 13, '8/13/2013', 1.34),
(1001309, 'USD', 13, '8/14/2013', 1.35),
(1001310, 'USD', 13, '8/15/2013', 1.36),
(1001311, 'USD', 13, '8/16/2013', 1.37),
(1001312, 'USD', 13, '8/19/2013', 1.38),
(1001313, 'USD', 13, '8/20/2013', 1.38),
(1001314, 'USD', 13, '8/21/2013', 1.37),
(1001315, 'USD', 13, '8/22/2013', 1.36),
(1001316, 'USD', 13, '8/23/2013', 1.35),
(1001317, 'USD', 13, '8/26/2013', 1.34),
(1001318, 'USD', 13, '8/27/2013', 1.33),
(1001319, 'USD', 13, '8/28/2013', 1.31),
(1001320, 'USD', 13, '8/29/2013', 1.32),
(1001321, 'USD', 13, '8/30/2013', 1.33)) as t(DATA_ID, CURR, CODE, [DATE], [RATE])
使用一个范围,例如2013-08-01到2013-08-31,我需要找出哪些天是=到周六和周日(周末)。我可以用datename(dw,CURR_RATES.DATE)函数轻松地完成这项工作
datename(dw, CURR_RATES.DATE) as weekday from CURR_RATES
DATA_ID CURR CODE DATE RATE Weekday
----------- ---- ----------- --------- ----- -----------
1001300 USD 13 8/1/2013 1.31 Thursday
1001301 USD 13 8/2/2013 1.32 Friday
1001302 USD 13 8/5/2013 1.33 Monday
1001303 USD 13 8/6/2013 1.34 Tuesday
1001304 USD 13 8/7/2013 1.35 Wednesday
1001305 USD 13 8/8/2014 1.31 Friday
1001306 USD 13 8/9/2013 1.32 Friday
1001307 USD 13 8/12/2013 1.33 Monday
1001308 USD 13 8/13/2013 1.34 Tuesday
1001309 USD 13 8/14/2013 1.35 Wednesday
1001310 USD 13 8/15/2013 1.36 Thursday
1001311 USD 13 8/16/2013 1.37 Friday
1001312 USD 13 8/19/2013 1.38 Monday
1001313 USD 13 8/20/2013 1.38 Tuesday
1001314 USD 13 8/21/2013 1.37 Wednesday
1001315 USD 13 8/22/2013 1.36 Thursday
1001316 USD 13 8/23/2013 1.35 Friday
1001317 USD 13 8/26/2013 1.34 Monday
1001318 USD 13 8/27/2013 1.33 Tuesday
1001319 USD 13 8/28/2013 1.31 Wednesday
1001320 USD 13 8/29/2013 1.32 Thursday
1001321 USD 13 8/30/2013 1.33 Friday
我需要做的是编写一个存储过程来查找丢失的星期六和星期天,并为它们插入行,将列速率的值设置为等于上一个星期五。该表可以包含其他月份的数据,因此我需要能够指定一个范围。此外,DATA_ID列需要包含新添加行的值。对于第一个插入的行,“数据ID”列的值应该是最后一行“数据ID+1”的值-第二个插入的行应该是新插入行的“数据ID+1”,依此类推…因此S.P.也需要计算表中最后一行的“数据ID”
希望这是足够清楚的-将感谢任何反馈或想法如何实施这一点
事先非常感谢
R00ty您可能需要修改
dbo.BuildDateRange
中的案例,以调整服务器的配置方式(SET DATEFIRST
)
用于构建日期范围之间所有日期的表的函数:-
create function dbo.BuildDataRange
(
@StartDate date,
@EndDate date
)
returns @returntable table
(
[Date] date,
PreviousFriday date
)
as
begin
while @StartDate<=@EndDate begin
insert into @returntable ([Date],PreviousFriday)
values (
@StartDate,
dateadd(d,
case datepart(dw,@StartDate)
when 1 then -2
when 2 then -3
when 3 then -4
when 4 then -5
when 5 then -6
when 6 then -7
when 7 then -1
end,@StartDate)
)
set @StartDate=DATEADD(day,1,@StartDate)
end
return
end
go
其中包含一些数据:-
insert into #curr_rates values
(1001299,'usd',13,'2013-07-31',1.25),
(1001300,'usd',13,'2013-08-01',1.31),
(1001301,'usd',13,'2013-08-02',1.32),
(1001302,'usd',13,'2013-08-05',1.33),
(1001303,'usd',13,'2013-08-06',1.34),
(1001304,'usd',13,'2013-08-07',1.35),
(1001305,'usd',13,'2013-08-08',1.31),
(1001306,'usd',13,'2013-08-09',1.32),
(1001307,'usd',13,'2013-08-12',1.33),
(1001308,'usd',13,'2013-08-13',1.34),
(1001309,'usd',13,'2013-08-14',1.35),
(1001310,'usd',13,'2013-08-15',1.36),
(1001311,'usd',13,'2013-08-16',1.37),
(1001312,'usd',13,'2013-08-19',1.38),
(1001313,'usd',13,'2013-08-20',1.38),
(1001314,'usd',13,'2013-08-21',1.37),
(1001315,'usd',13,'2013-08-22',1.36),
(1001316,'usd',13,'2013-08-23',1.35),
(1001317,'usd',13,'2013-08-26',1.34),
(1001318,'usd',13,'2013-08-27',1.33),
(1001319,'usd',13,'2013-08-28',1.31),
(1001320,'usd',13,'2013-08-29',1.32),
(1001321,'usd',13,'2013-08-30',1.33)
go
插入缺失数据的SP(将用前一个星期五的费率填补任何空白,因此请确保只缺少周末
create procedure dbo.InsertWeekends
(
@from date,
@to date
) as
begin
declare @watermark int
select @watermark=max(data_id)
from #curr_rates
insert into #curr_rates
select @watermark+ROW_NUMBER() over(order by dr.[date]) as data_id,
cr.curr,
cr.code,
dr.[date],
cr.rate
from dbo.BuildDataRange(@from,@to) dr
join #curr_rates cr on cr.date=dr.PreviousFriday
where not exists(
select *
from #curr_rates csq
where csq.[date]=dr.[Date]
and csq.curr=cr.curr
and csq.code=cr.code
)
end
go
用法:-
exec dbo.InsertWeekends '2013-08-01', '2013-08-31'
go
因此:-
select *
from #curr_rates
order by [date]
go
产生:-
您可能需要修改dbo.BuildDateRange
中的案例,以调整服务器的配置方式(SET DATEFIRST
)
用于构建日期范围之间所有日期的表的函数:-
create function dbo.BuildDataRange
(
@StartDate date,
@EndDate date
)
returns @returntable table
(
[Date] date,
PreviousFriday date
)
as
begin
while @StartDate<=@EndDate begin
insert into @returntable ([Date],PreviousFriday)
values (
@StartDate,
dateadd(d,
case datepart(dw,@StartDate)
when 1 then -2
when 2 then -3
when 3 then -4
when 4 then -5
when 5 then -6
when 6 then -7
when 7 then -1
end,@StartDate)
)
set @StartDate=DATEADD(day,1,@StartDate)
end
return
end
go
其中包含一些数据:-
insert into #curr_rates values
(1001299,'usd',13,'2013-07-31',1.25),
(1001300,'usd',13,'2013-08-01',1.31),
(1001301,'usd',13,'2013-08-02',1.32),
(1001302,'usd',13,'2013-08-05',1.33),
(1001303,'usd',13,'2013-08-06',1.34),
(1001304,'usd',13,'2013-08-07',1.35),
(1001305,'usd',13,'2013-08-08',1.31),
(1001306,'usd',13,'2013-08-09',1.32),
(1001307,'usd',13,'2013-08-12',1.33),
(1001308,'usd',13,'2013-08-13',1.34),
(1001309,'usd',13,'2013-08-14',1.35),
(1001310,'usd',13,'2013-08-15',1.36),
(1001311,'usd',13,'2013-08-16',1.37),
(1001312,'usd',13,'2013-08-19',1.38),
(1001313,'usd',13,'2013-08-20',1.38),
(1001314,'usd',13,'2013-08-21',1.37),
(1001315,'usd',13,'2013-08-22',1.36),
(1001316,'usd',13,'2013-08-23',1.35),
(1001317,'usd',13,'2013-08-26',1.34),
(1001318,'usd',13,'2013-08-27',1.33),
(1001319,'usd',13,'2013-08-28',1.31),
(1001320,'usd',13,'2013-08-29',1.32),
(1001321,'usd',13,'2013-08-30',1.33)
go
插入缺失数据的SP(将用前一个星期五的费率填补任何空白,因此请确保只缺少周末
create procedure dbo.InsertWeekends
(
@from date,
@to date
) as
begin
declare @watermark int
select @watermark=max(data_id)
from #curr_rates
insert into #curr_rates
select @watermark+ROW_NUMBER() over(order by dr.[date]) as data_id,
cr.curr,
cr.code,
dr.[date],
cr.rate
from dbo.BuildDataRange(@from,@to) dr
join #curr_rates cr on cr.date=dr.PreviousFriday
where not exists(
select *
from #curr_rates csq
where csq.[date]=dr.[Date]
and csq.curr=cr.curr
and csq.code=cr.code
)
end
go
用法:-
exec dbo.InsertWeekends '2013-08-01', '2013-08-31'
go
因此:-
select *
from #curr_rates
order by [date]
go
产生:-
展示您目前的情况。“与上周五持平”即使您错过了一个星期天,但没有相应的星期六?您好。谢谢您的回复!总是会错过周末。因此,对于上面的表格,星期六和星期天都需要插入值为1,34的值。然后在第二个星期五之后,星期六和星期天都需要插入值为1,32的值,依此类推…显示您需要插入的内容到目前为止,“相当于上周五”即使您错过了一个星期天,但没有相应的星期六?您好。谢谢您的回复!总是会错过周末。因此,对于上面的表格,星期六和星期天都需要插入值为1,34的值。然后在第二个星期五之后,星期六和星期天都需要插入值为1,32的值,依此类推…非常感谢非常感谢!这非常有帮助。再次感谢。非常感谢!这非常有帮助。再次感谢。