2011-05-11 72 views
4

我有一張表,用於存儲StartDate和開始日期的星期幾的名稱。我不知道爲什麼,這是糟糕的設計,但我沒有創造它,也無法改變它。所以當然,現在我們有一些不符合星期幾的日期。更糟糕的是,星期幾是正確的,開始日期不正確。所以我需要做的是調整日期,以便每行的StartDate落在該行的DayOfWeek上。我們可以假設StartDate始終是最小值,因此目標日期將是當前設置的StartDate之後的第一個[DayOfWeek]。調整日期以匹配保存的一週的日期

所以,比如我有看起來像這樣的行(10年8月23日是週一,10年8月29日是個星期日):

StartDate DayOfWeek 
----------------------- 
2010-08-23 Monday 
2010-08-23 Tuesday 
2010-08-29 Thursday 

在第2行,你可以看到日期是應該是星期二,但實際上是星期一。我需要結束與此:

StartDate DayOfWeek 
----------------------- 
2010-08-23 Monday 
2010-08-24 Tuesday 
2010-09-02 Thursday 

我總是努力工作的日期,但SQL也不是我最強的技能。謝謝。

回答

3

偷geofftnz的設置,並希望這是「聰明」的方法,他在想:

declare @baddata table(StartDate datetime, [DayOfWeek] varchar(20)) 
insert into @baddata values('2010-08-23','Monday') 
insert into @baddata values('2010-08-23','Tuesday') 
insert into @baddata values('2010-08-29','Thursday') 

select * from @baddata 

;with Nums as (
    select 0 as n union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 
) 
update b 
set StartDate = DATEADD(day,Nums.n,StartDate) 
from 
    @baddata b 
     inner join 
    Nums 
     on 
      DATENAME(weekday,DATEADD(day,Nums.n,StartDate)) = [DayOfWeek] 

select * from @baddata 

對於第三排,我得到在九月的日期,而不是8月,但我認爲結果是正確的,你的樣本結果是不正確的?

+0

我喜歡它!我一直在用我正在嘗試的東西掛斷DateFirst問題。在我的例子中,我意外地有8月份而不是9月份,抱歉讓我感到困惑。我糾正了它,讓其他人免於混淆。非常感謝你。 – xr280xr 2011-05-11 13:57:38

3

將會有一個聰明的方法來做到這一點,並且「讓我們僅僅打出一些數據」的方式。下面是後者:

-- here's our bad data we want to fix: 
declare @baddata table(StartDate datetime, [DayOfWeek] varchar(20)) 
insert into @baddata values('2010-08-23','Monday') 
insert into @baddata values('2010-08-23','Tuesday') 
insert into @baddata values('2010-08-29','Thursday') 

-- we need to create a table containing valid date+day pairs for the 
-- range of our bad data 

-- find max and min dates from our bad data 
declare @MinDate datetime 
declare @MaxDate datetime 

select @MinDate = min(StartDate), @MaxDate = max(StartDate) from @baddata 

-- offset max date by 7 days (which is the most we'll need to correct the date by) 
set @MaxDate = dateadd(day,7,@MaxDate) 

-- create a table matching dates to days 
declare @dates table([Date] Datetime, [DayOfWeek] varchar(20)) 

declare @i int 

-- populate the table with enough days to cover the range of your bad data 
set @i = 0 
while @i <= datediff(day,@MinDate, @MaxDate) 
begin 
    insert into @dates 
    select dateadd(day, @i, @MinDate), datename(dw,dateadd(day, @i, @MinDate)) 

    set @i = @i + 1 
end 

-- show us our table 
select * from @dates 


-- update the ones with incorrect days 
update bd 
set 
    bd.StartDate = (-- find the next date with a matching day 
     select top 1 
      d.[Date] 
     from 
      @dates d 
     where 
      d.[DayOfWeek] = bd.[DayOfWeek] and 
      d.[Date] >= bd.StartDate 
     order by 
      d.[Date] 
    ) 
from 
    @baddata bd 
     inner join @dates d on 
      d.[Date] = bd.StartDate 
where 
    bd.[DayOfWeek] != d.[DayOfWeek] -- date names don't match 

select * from @baddata 
+0

非常感謝geofftnz。這似乎完成了目標就好了。我更喜歡達米恩的方法,因爲它的簡潔性,如果日期範圍很大,它似乎更有效率。感謝您的幫助和評論。 – xr280xr 2011-05-11 14:04:34

+0

是的,達米安的方法看起來更好,尤其是如果它要定期運行的話。如果這是一次性修復工作,那麼這並不重要(除非我們正在討論需要幾分鐘或幾小時運行的查詢)。 – geofftnz 2011-05-11 23:43:26