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
Slightly similar approach to aforementioned solution, but just a one-liner that could be used inside a function or inline for computed column.
Assumptions:
If you'd rather it be different, change the date '18991231' to a date with the weekday that you'd like to equal 1. The convert() function is key to making the whole thing work - cast does NOT do the trick:
((datediff(day, convert(datetime, '18991231', 112), @dt) % 7) + 1)
I know this post is way-super-old, but I was trying to do a similar thing and came up with a different solution and figured I'd post for posterity. Plus I did some searching around and did not find much content on this question.
In my case, I was trying to use a computed column PERSISTED, which requires the calculation to be deterministic. The calculation I used is:
datediff(dd,'2010-01-03',[DateColumn]) % 7 + 1
The idea is to figure out a known Sunday that you know will occur before any possible date in your table (in this case, Jan 3 2010), then calculate the modulo 7 + 1 of the number of days since that Sunday.
The problem is that including a literal date in the function call is enough to mark it as non-deterministic. You can work around that by using the integer 0 to represent the epoch, which for SQL Server is Jan 1st, 1900, a Sunday.
datediff(dd,0,[DateColumn]) % 7 + 1
The +1 just makes the result work the same as datepart(dw,[datecolumn]) when datefirst is set to 7 (default for US), which sets Sunday to 1, Monday to 2, etc
I can also use this in conjunction with case [thatComputedColumn] when 1 then 'Sunday' when 2 then 'Monday' ... etc. Wordier, but deterministic, which was a requirement in my environs.
Ok, i figured it..
CREATE FUNCTION [dbo].[FN_DayNumeric_DateTime]
(@DT DateTime)
RETURNS INT WITH SCHEMABINDING
AS
BEGIN
DECLARE @Result int
DECLARE @FIRST_DATE DATETIME
SELECT @FIRST_DATE = convert(DATETIME,-53690+((7+5)%7),112)
SET @Result = datediff(dd,dateadd(dd,(datediff(dd,@FIRST_DATE,@DT)/7)*7,@FIRST_DATE), @DT)
RETURN (@Result)
END
GO
Not sure what you are looking for, but if this is part of a website, try this php function from http://php.net/manual/en/function.date.php
function weekday($fyear, $fmonth, $fday) //0 is monday
{
return (((mktime ( 0, 0, 0, $fmonth, $fday, $fyear) - mktime ( 0, 0, 0, 7, 17, 2006))/(60*60*24))+700000) % 7;
}
Although this is old. Commenting simple answer to help future readers. @liver-larson was almost correct. Made a wrong assumption of epoch time 0 (Jan 1st, 1900) being a Sunday. It is actually a Monday.
Wrong code - https://stackoverflow.com/a/20481717/2012977
datediff(dd,0,[DateColumn]) % 7 + 1
Correction
datediff(dd,-1,[DateColumn]) % 7 + 1
I like this answer because there is no date conversion happening and guaranteed deterministic.
Unit test of code. Sadly SqlFiddle down at the moment of writing. Note hardcoding column value here. Expect column to be a date type.
SELECT DATEPART(WEEKDAY, '2020-06-14'), DATEDIFF(dd, -1, '2020-06-14') % 7 + 1
SELECT DATEPART(WEEKDAY, '2020-06-15'), DATEDIFF(dd, -1, '2020-06-15') % 7 + 1
SELECT DATEPART(WEEKDAY, '2020-06-16'), DATEDIFF(dd, -1, '2020-06-16') % 7 + 1
SELECT DATEPART(WEEKDAY, '2020-06-17'), DATEDIFF(dd, -1, '2020-06-17') % 7 + 1
SELECT DATEPART(WEEKDAY, '2020-06-18'), DATEDIFF(dd, -1, '2020-06-18') % 7 + 1
SELECT DATEPART(WEEKDAY, '2020-06-19'), DATEDIFF(dd, -1, '2020-06-19') % 7 + 1
SELECT DATEPART(WEEKDAY, '2020-06-20'), DATEDIFF(dd, -1, '2020-06-20') % 7 + 1