Question

In SQL server you can use the DATENAME function to get the day of week as a string

declare @date datetime
set @date = '12/16/08'
select datename(dw, @date)

which returns "Tuesday"

and you can use the DATEPART function to get the day of week as an integer

declare @date datetime
set @date = '12/16/08'
select datepart(dw, @date)

Which returns 3

But say I have a varchar that contains the string "Tuesday" and I want to convert it to its integer representation of 3. Sure, I could write out the conversion without much hassle, but I'd much rather use a built-in function. Does such a function exist?

Was it helpful?

Solution

Rather than write a function, you should create a days of the week table with the description and the numeric value. THen you can simply join to the table to get the numeric.

And if you have days stored multiple ways (likely in a characterbased system), you can put all the variants into the table, so TUE, Tues., Tuesday would all map to the same integer.

OTHER TIPS

unfortunately there isn't a built in function, but you can create your own like this:


CREATE FUNCTION dbo.WeekDay(@DayOfWeek Varchar(9))
RETURNS INT
            AS
    BEGIN
    DECLARE @iDayofWeek INT
    SELECT @iDayofWeek = CASE @DayOfWeek
                    WHEN 'Sunday' THEN 1
                    WHEN 'Monday' THEN 2
                    WHEN 'Tuesday' THEN 3
                    WHEN 'Wednesday' THEN 4
                    WHEN 'Thursday' THEN 5
                    WHEN 'Friday' THEN 6
                    WHEN 'Saturday' THEN 7
        END
    RETURN (@iDayofWeek)
    END
GO

Well 6 years later and several version of SQL Server but there still no built-in function to do this (as far as I know). Not sure if will something to do this.

I took similar approach to @RussBradberry just done with IF statements.

CREATE FUNCTION dbo.WeekDayInt (@DayOfWeekName VARCHAR(10))
RETURNS INT
AS
    BEGIN
        DECLARE @DayWeekNumber INT
        IF @DayOfWeekName = 'Sunday'    SET @DayWeekNumber = 1
        IF @DayOfWeekName = 'Monday'    SET @DayWeekNumber = 2
        IF @DayOfWeekName = 'Tuesday'   SET @DayWeekNumber = 3
        IF @DayOfWeekName = 'Wednesday' SET @DayWeekNumber = 4
        IF @DayOfWeekName = 'Thursday'  SET @DayWeekNumber = 5
        IF @DayOfWeekName = 'Friday'    SET @DayWeekNumber = 6
        IF @DayOfWeekName = 'Saturday'  SET @DayWeekNumber = 7;
        RETURN (@DayWeekNumber)
    END

or as alternative it can be done this way, which can be a little faster because it will return value as soon as match is encountered and not try to evaluate other values.

CREATE FUNCTION dbo.WeekDayInt (@DayOfWeekName VARCHAR(10))
RETURNS INT
AS
    BEGIN
        IF @DayOfWeekName = 'Sunday'    RETURN 1
        IF @DayOfWeekName = 'Monday'    RETURN 2
        IF @DayOfWeekName = 'Tuesday'   RETURN 3
        IF @DayOfWeekName = 'Wednesday' RETURN 4
        IF @DayOfWeekName = 'Thursday'  RETURN 5
        IF @DayOfWeekName = 'Friday'    RETURN 6
        IF @DayOfWeekName = 'Saturday'  RETURN 7;
        RETURN 0;
    END

Here is a dirty alternative that I use if I'm not running it on massive dataset.

    Select CHARINDEX(SUBSTRING('Thursday',1,3), 'MONTUEWEDTHUFRISATSUN') / 3 + 1

Just replace Thursday with a day of your choice or a variable.

How it works: SUBSTRING('Thursday',1,3) basically creates Thu, then charindex finds out the position of thu in the string which is 10. We then divide 10 by length of our day words which is 3 which equals 3, and because I want

Monday to equal 1 Tuesday to equal 2 Wednesday to equal 3 Thursday to equal 4

I add 1 to the end

so the result is 4.

Hope that helps someone, but I agree it probably isn't the best solution.

Note: You can also order a result set by day number by using it like so:

SELECT ID,DayNamesColumn from mytable ORDER BY CHARINDEX(SUBSTRING(DayNamesColumn ,1,3), 'MONTUEWEDTHUFRISATSUN') / 3 + 1

You can use the following select to get the iso weekday ordinal of date 2017-12-15 with respect to (e.g. regardless of) the current setting of @@datefirst which determines the first day of the week. E.g. set datefirst = 1 for monday.

select
  w.weekday_id_iso8601,
  w.weekday_id_datepart,
  w.weekday_name
from (
       values
         (7, 'Monday'),
         (8, 'Tuesday'),
         (9, 'Wednesday'),
         (10, 'Thursday'),
         (11, 'Friday'),
         (12, 'Saturday'),
         (13, 'Sunday'))
     t(weekday_id, weekday_name)
cross apply (
  select
    t.weekday_id - 6 weekday_id_iso8601,
    (t.weekday_id - @@datefirst + 1) % 7 + 1 weekday_id_datepart,
    t.weekday_name
) w
where w.weekday_id_datepart = datepart(weekday, '2017-12-15')

I disagree with the answer about adding a lookup table, since in this case, the values are limited and will never change. The lookup table join will just add cost.

IMHO; since you have limited values, I would just use a case statement in my views. It's not pretty, but it's probably the fastest way to do it.

This may not serve a practical purpose, but I thought I'd figure it out just for fun. :) The following works.

Remember that when using DATEPART or DATENAME that the value of @@DATEFIRST is important and can change your results. Look up SET DATEFIRST in the online help.

DECLARE
    @date_name AS VARCHAR(20)

SET @date_name = 'Monday'

SELECT
    DATEPART(dw, my_date)
FROM
    (
    SELECT CAST('1900-01-01' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-02' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-03' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-04' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-05' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-06' AS DATETIME) AS my_date UNION
    SELECT CAST('1900-01-07' AS DATETIME) AS my_date
    ) AS My_Dates
WHERE
    DATENAME(dw, my_date) = @date_name

Where DayID is integer value 1 thru 7.

Add DayID to a some base date such as 1899-12-31. (If Sunday is first day of week then use initial date of 1899-12-30)

1900-01-01 was Monday, 1900-01-02 was Tuesday, and so on.

Thus :

select DayID, 
       datename( weekday, dateadd( day, DayID, '18991231' ) ) 

In SQL 2014, you can use:

SELECT DATEPART(DW, GetDate()) This will return day of week as integer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top