Sql 调整日期以匹配保存的星期几
我有一个表,存储StartDate和开始日期所在的星期天的名称。我不知道为什么,这是一个糟糕的设计,但我没有创造它,不能改变它。当然,现在我们有一些日期与一周中的某一天不匹配。更糟糕的是,星期几是正确的,开始日期是错误的。所以我需要做的是调整日期,使每一行的开始日期落在该行的星期几。我们可以假设StartDate始终是最小值,因此目标日期将是当前设置的StartDate之后的第一个[星期几] 例如,我有一些行,看起来像8/23/10是周一,8/29/10是太阳:Sql 调整日期以匹配保存的星期几,sql,tsql,date,dayofweek,Sql,Tsql,Date,Dayofweek,我有一个表,存储StartDate和开始日期所在的星期天的名称。我不知道为什么,这是一个糟糕的设计,但我没有创造它,不能改变它。当然,现在我们有一些日期与一周中的某一天不匹配。更糟糕的是,星期几是正确的,开始日期是错误的。所以我需要做的是调整日期,使每一行的开始日期落在该行的星期几。我们可以假设StartDate始终是最小值,因此目标日期将是当前设置的StartDate之后的第一个[星期几] 例如,我有一些行,看起来像8/23/10是周一,8/29/10是太阳: StartDate Day
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也不是我最强的技能。谢谢。将有一种聪明的方法来实现这一点,让我们把一些数据处理掉。以下是后者:
-- 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
偷了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
第三排的日期是9月,不是8月,但我认为结果是正确的,而你的样本结果是错误的?我喜欢它!我一直因为约会第一的问题而被挂断电话,因为我一直在尝试。在我的示例中,我确实意外地使用了八月而不是九月,很抱歉造成混淆。我更正了它,以免其他人产生同样的困惑。非常感谢,非常感谢杰弗里茨。这似乎很好地实现了目标。我更喜欢Damien的方法,因为它简洁,而且如果日期范围大,它似乎更有效。我感谢你的帮助和评论。是的,达米恩的方法看起来更好,特别是如果它将定期运行的话。如果这是一个一次性的修复工作,那么这并不重要,当然,除非我们讨论的是需要几分钟或几小时才能运行的查询。