2013-10-31 35 views
1

我在這裏有一個小開發挑戰。我已在SQL Server中下表CURR_RATES:使用範圍,例如2013年8月1日至2013年8月31日需要存儲過程來查找缺失的間隙並插入行

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]) 

而且,我需要找到哪些日子=到週六和週日(週末)。我可以用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列需要包含新添加的行的值。對於第一個插入的行,DATA_ID列的值應該是最後一行的值DATA_ID +1 - 第二個插入的行應該是新插入的行的DATA_ID +1,等等....所以SP需要找出表中最後一行的DATA_ID。

希望這已經夠清楚了 - 希望瞭解有關如何實現此目的的任何反饋或意見。

非常感謝您提前。

R00ty

+0

顯示你有什麼至今。 – RBarryYoung

+0

_「等於上一個星期五_ _即使你錯過了一個星期天,但不是它相應的星期六_? – geomagas

+0

嗨。感謝您的回覆!總會有周末失蹤。所以對於上面的表格,星期六和星期天需要插入1,34的值。然後在第二個星期五,星期六和星期天需要插入值爲1,32等等...... – R00ter

回答

1

您可能需要在dbo.BuildDateRangecase鼓搗來調整您的服務器的配置(SET DATEFIRST

一個函數建立日期範圍之間的所有日期的表: -

create function dbo.BuildDataRange 
(
    @StartDate date, 
    @EndDate date 
) 
returns @returntable table 
(
    [Date] date, 
    PreviousFriday date 
) 
as 
begin 
    while @StartDate<[email protected] 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 

測試數據的表: -

create table #curr_rates (
    data_id int, 
    curr char(3), 
    code int, 
    [date] datetime, 
    rate decimal(10,5) 
) 
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 

生產: -

enter image description here

+0

您顯然需要使代碼更具防禦性;但這是一個開始... – dav1dsm1th

+1

非常感謝!這非常有幫助。再次感謝。 – R00ter