Sql 需要存储过程来查找缺少的间隙并插入行

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',

我这里有一个小的开发挑战。我在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', 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的值,依此类推…非常感谢非常感谢!这非常有帮助。再次感谢。非常感谢!这非常有帮助。再次感谢。