Deterministic scalar function to get day of week for a date

后端 未结 11 1532
孤街浪徒
孤街浪徒 2021-01-13 00:10

SQL Server, trying to get day of week via a deterministic UDF.

Im sure this must be possible, but cant figure it out.

UPDATE: SAMPLE CODE..

C         


        
相关标签:
11条回答
  • 2021-01-13 00:20

    There is an already built-in function in sql to do it:

    SELECT DATEPART(weekday, '2009-11-11')
    

    EDIT: If you really need deterministic UDF:

    CREATE FUNCTION DayOfWeek(@myDate DATETIME ) 
    RETURNS int
    AS
    BEGIN
    RETURN DATEPART(weekday, @myDate)
    END
    GO
    SELECT dbo.DayOfWeek('2009-11-11')
    

    EDIT again: this is actually wrong, as DATEPART(weekday) is not deterministic.

    UPDATE: DATEPART(weekday) is non-deterministic because it relies on DATEFIRST (source).
    You can change it with SET DATEFIRST but you can't call it inside a stored function.

    I think the next step is to make your own implementation, using your preferred DATEFIRST inside it (and not considering it at all, using for example Monday as first day).

    0 讨论(0)
  • 2021-01-13 00:22

    The day of the week? Why don't you just use DATEPART?

    DATEPART(weekday, YEAR_DATE)
    
    0 讨论(0)
  • 2021-01-13 00:24

    Can't you just select it with something like:

    SELECT DATENAME(dw, GETDATE());
    
    0 讨论(0)
  • 2021-01-13 00:25

    The proposed solution has one problem - it returns 0 for Saturdays. Assuming that we're looking for something compatible with DATEPART(WEEKDAY) this is an issue.

    Nothing a simple CASE statement won't fix, though.

    0 讨论(0)
  • 2021-01-13 00:28

    Taken from Deterministic scalar function to get week of year for a date

    ;
    with 
    Dates(DateValue) as 
    (
        select cast('2000-01-01' as date)
        union all 
        select dateadd(day, 1, DateValue) from Dates where DateValue < '2050-01-01'
    )
    select 
        year(DateValue) * 10000 + month(DateValue) * 100 + day(DateValue) as DateKey, DateValue,        
        datediff(day, dateadd(week, datediff(week, 0, DateValue), 0), DateValue) + 2 as DayOfWeek,
        datediff(week, dateadd(month, datediff(month, 0, DateValue), 0), DateValue) + 1 as WeekOfMonth,
        datediff(week, dateadd(year, datediff(year, 0, DateValue), 0), DateValue) + 1 as WeekOfYear
        from Dates option (maxrecursion 0)
    
    0 讨论(0)
  • 2021-01-13 00:32

    Make a function, and have @dbdate varchar(8) as your input variable.

    Have it return the following:

    RETURN (DATEDIFF(dd, -1, convert(datetime, @dbdate, 112)) % 7)+1;
    

    The value 112 is the sql style YYYYMMDD.

    This is deterministic because the datediff does not receive a string input, if it were to receive a string it would no longer work because it internally converts it to a datetime object. Which is not deterministic.

    0 讨论(0)
提交回复
热议问题