调整日期以匹配保存的星期几

发布于 2024-11-06 11:46:46 字数 635 浏览 5 评论 0原文

我有一个表,用于存储开始日期和开始日期所在的星期几的名称。我不知道为什么,这是糟糕的设计,但我没有创建它,也无法更改它。当然,现在我们有一些日期与星期几不匹配。更糟糕的是,星期几是正确的,而开始日期是不正确的。所以我需要做的是调整日期,使每行的 StartDate 落在该行的 DayOfWeek 上。我们可以假设 StartDate 始终是最小值,因此目标日期将是当前设置的 StartDate 之后的第一个 [DayOfWeek]。

例如,我的行看起来像这样(8/23/10 是星期一,8/29/10 是星期日):

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 也不是我最强的技能。谢谢。

I have a table that stores a StartDate and the name of the day of week that start date falls on. I don't know why, it is bad design but I didn't create it and can't change it. So of course, now we have some dates that don't match the day of week. To make it worse, the day of week is correct and the start date is incorrect. So what I need to do is adjust the dates so that each row's StartDate falls on that row's DayOfWeek. We can assume StartDate is always the minimum value so the target date will be the first [DayOfWeek] after the currently set StartDate.

So for example I have rows that look like this (8/23/10 was a Mon, 8/29/10 was a Sun):

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

In row 2 you can see the date is supposed to be a Tuesday but it's actually a Monday. I need to end up with this:

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

I always struggle when working with dates, but SQL is also not my strongest skill either. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

平安喜乐 2024-11-13 11:46:46

窃取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

对于第三行,我得到的日期是九月,而不是八月,但我认为结果是正确的,而你的样本结果是不正确的?

Stealing geofftnz's setup, and hoping this is the "clever" method he was thinking of:

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

For the third row, I'm getting a date in September, not August, but I think that the result is right and your sample result is incorrect?

通知家属抬走 2024-11-13 11:46:46

将会有一种聪明的方法来做到这一点,并且有一种“让我们把一些数据敲出来”的方法。这是后者:

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

There will be a clever way of doing this and a "let's just bash some data out" way. Here is the latter:

-- 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文