寻找最近的未来日期

时间:2014-10-15 10:06:40

标签: sql sql-server-2008 tsql

是否可以通过日期varchar值找到最接近的未来日期(日期时间)?

鉴于,

DECLARE @DayValue VARCHAR(3)
 , @DateValue DATETIME 
SET @DayValue = 'Tue' -- Values could be 'Mon', 'Tue', 'Wed' and etc. 
SET @DateValue = '10/15/2014' -- Format is MM/dd/yyyy

我想得到:

Oct 21 2014 12:00AM

5 个答案:

答案 0 :(得分:2)

使用循环,

    DECLARE @DayValue VARCHAR(3) 
            ,@DateValue DATETIME 
    SET     @DayValue = 'tue'
    SET     @DateValue = '10/15/2014'
    declare @i  int= 1  ,@day varchar(3) = null
    while (@i<=7 )
        begin 

        Select @day = left(datename (dw,@DateValue),3)

            if  @day = @DayValue
                begin 
                    Select  @DateValue
                    break
                end 

        Select @DateValue = @DateValue+ 1

        Select @i = @i+1

        end 

答案 1 :(得分:1)

如果您有日期表,则可以使用此功能:

CREATE FUNCTION [dbo].[GetNextDayOfWeek] 
(   @DayOfWeek      VARCHAR(3),
    @DateValue     datetime
)
RETURNS SmallDateTime 
AS
BEGIN
    DECLARE @NextDayOfWeek smalldatetime
    SET @NextDayOfWeek = (
    SELECT 
        MIN(d.Date) 
    FROM 
        tDefDate d
    WHERE 
        d.Date > @DateValue
    AND LEFT(DATENAME(Weekday, d.Date), 3) = @DayOfWeek);
    RETURN @NextDayOfWeek
END

然后它很简单:

select [dbo].[GetNextDayOfWeek]('Tue', Getdate()) -- next tuesday=> 2014-10-21

请注意,它需要考虑数据库的语言。所以,如果它是德语:

select [dbo].[GetNextDayOfWeek]('Die', Getdate()) -- next tuesday(Dienstag)

这里的版本也没有日期表(但效率较低)。

CREATE FUNCTION [dbo].[GetNextDayOfWeek] 
(   @DayOfWeek      VARCHAR(3),
    @DateValue     datetime
)
RETURNS SmallDateTime 
AS
BEGIN
    DECLARE @NextDayOfWeek smalldatetime

    ;WITH CTE as
    (
        SELECT GetDate() DateValue, DayNum=0

        UNION ALL

        SELECT DateValue + 1, DayNum=DayNum+1
        FROM  CTE
        WHERE DayNum <=7 
    )
    SELECT @NextDayOfWeek = (
        SELECT 
            MIN(d.DateValue) 
        FROM 
            CTE d
        WHERE d.DateValue > @DateValue
        AND   LEFT(DATENAME(Weekday, d.DateValue), 3) = @DayOfWeek
    )OPTION (MAXRECURSION 8);
    RETURN @NextDayOfWeek
END

答案 2 :(得分:1)

如果您可以将DayValue定义为整数,则可以更优雅的方式解决此问题:

DECLARE @DayValue int, @DateValue DATETIME 
SET @DayValue = 3 -- Values could be 1-Sun, 2-Mon, 3-Tue, 4-Wed and etc. 
SET @DateValue = '10/15/2014' -- Format is MM/dd/yyyy

select dateadd(day,(7 + @DayValue - datepart(w,@DateValue)), @DateValue)

尝试 SQL FIDDLE DEMO

答案 3 :(得分:0)

没有循环,可以在多行的选择中使用。 :)

DECLARE @DayValue CHAR(3)
DECLARE @DateValue DATETIME
DECLARE @FutureDate DATE
SET @DayValue='MON'
SET @DateValue='10/12/2014'

DECLARE @Days TABLE
(
    [DayOfWeek] TINYINT,
    [DayValue] CHAR(3)
)

INSERT INTO @Days([DayOfWeek],[DayValue])
    SELECT 0,'SUN' UNION
    SELECT 1,'MON' UNION
    SELECT 2,'TUE' UNION
    SELECT 3,'WED' UNION
    SELECT 4,'THU' UNION
    SELECT 5,'FRI' UNION
    SELECT 6,'SAT'


SET @FutureDate=
    DATEADD(DAY,
        --Skip to next week if we are already on the desired day or past it
        + CASE WHEN ((SELECT [DayOfWeek] FROM @Days WHERE [DayValue]=@DayValue)<DATEPART(WEEKDAY,@DateValue)) THEN 7 ELSE 0 END

        --reset to start of week (add one as DATEPART is base 1, not base 0)
        - DATEPART(WEEKDAY,@DateValue) + 1

        --Add the desired day of the week
        + (SELECT [DayOfWeek] FROM @Days WHERE [DayValue]=@DayValue)

        ,@DateValue)

SELECT @FutureDate

答案 4 :(得分:0)

这是一个有点粗糙的解决方案,但它的工作原理。 :)

SET DATEFIRST 1
DECLARE @DateValue DateTime
 , @DayValue VARCHAR(3)
 , @tmp INT
SET @DateValue = '09/30/2014'
SET @DayValue = 'wed'
SET @tmp = CASE @DayValue
    WHEN 'Mon' THEN (1 - DATEPART(dw, @DateValue) + 7) % 7
    WHEN 'Tue' THEN (2 - DATEPART(dw, @DateValue) + 7) % 7
    WHEN 'Wed' THEN (3 - DATEPART(dw, @DateValue) + 7) % 7
    WHEN 'Thu' THEN (4 - DATEPART(dw, @DateValue) + 7) % 7
    WHEN 'Fri' THEN (5 - DATEPART(dw, @DateValue) + 7) % 7
    WHEN 'Sat' THEN (6 - DATEPART(dw, @DateValue) + 7) % 7
    WHEN 'Sun' THEN (7 - DATEPART(dw, @DateValue) + 7) % 7
END
SELECT 
 CASE 
    WHEN @tmp = 0 THEN DATEADD (DAY, 7, @DateValue)
    ELSE DATEADD (DAY, @tmp, @DateValue)
   END