SQL Server,尝试通过确定性UDF获取星期几。
我确信这一定是可能的,但无法弄明白。
更新:示例代码..
CREATE VIEW V_Stuff WITH SCHEMABINDING AS
SELECT
MD.ID,
MD.[DateTime]
...
dbo.FN_DayNumeric_DateTime(MD.DateTime) AS [Day],
dbo.FN_TimeNumeric_DateTime(MD.DateTime) AS [Time],
...
FROM {SOMEWHERE}
GO
CREATE UNIQUE CLUSTERED INDEX V_Stuff_Index ON V_Stuff (ID, [DateTime])
GO
答案 0 :(得分:6)
好的,我认为..
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
答案 1 :(得分:6)
与上述解决方案略有相似的方法,但只是一个可以在函数内部使用的单行程序或计算列的内联。
假设:
如果您想要与众不同,请将日期'18991231'更改为您希望等于1的工作日的日期.convert()函数是使整个工作正常工作的关键 - 强制转换不是诀窍:
((datediff(day,convert(datetime, '18991231',112),@ dt)%7) + 1)
答案 2 :(得分:1)
取自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)
答案 3 :(得分:1)
我知道这篇文章已经超级老了,但是我试图做一个类似的事情,想出了一个不同的解决方案,并认为我会为后代发帖。另外,我做了一些搜索,并没有找到关于这个问题的更多内容。
就我而言,我试图使用计算列PERSISTED,这要求计算是确定性的。我使用的计算是:
datediff(dd,'2010-01-03',[DateColumn]) % 7 + 1
我们的想法是找出一个已知的星期日,你知道会在你的表格中任何可能的日期之前发生(在这种情况下,2010年1月3日),然后计算自该星期日以来天数的模数7 + 1。
问题是在函数调用中包含一个文字日期足以将其标记为非确定性。您可以通过使用整数0来表示时间来解决这个问题,对于SQL Server是1900年1月1日,这是一个星期日。
datediff(dd,0,[DateColumn]) % 7 + 1
当datefirst设置为7(默认为美国)时,+1只会使结果与datepart(dw,[datecolumn])相同,它将星期日设置为1,将星期一设置为2,等等
我也可以结合案例[thatComputedColumn]当1然后'星期日'时2然后'星期一'......等等,但是确定性的,这是我周围的要求。
答案 4 :(得分:0)
在sql中有一个已经内置的函数来执行它:
SELECT DATEPART(weekday, '2009-11-11')
修改强>: 如果你真的需要确定性UDF:
CREATE FUNCTION DayOfWeek(@myDate DATETIME )
RETURNS int
AS
BEGIN
RETURN DATEPART(weekday, @myDate)
END
GO
SELECT dbo.DayOfWeek('2009-11-11')
再次编辑:这实际上是错误的,因为DATEPART(weekday)
不是确定性的。
<强>更新强>:
DATEPART(weekday)
是非确定性的,因为它依赖于DATEFIRST
(source)
您可以使用SET DATEFIRST
更改它,但不能在存储的函数内调用它。
我认为下一步是make your own implementation,在其中使用您首选的DATEFIRST(根本不考虑它,例如使用 Monday 作为第一天)。
答案 5 :(得分:0)
建议的解决方案有一个问题 - 它在周六返回0。假设我们正在寻找与DATEPART(WEEKDAY)
兼容的内容,这是一个问题。
不过,简单的CASE
语句不会修复。
答案 6 :(得分:0)
创建一个函数,并将@dbdate varchar(8)作为输入变量。
让它返回以下内容:
RETURN (DATEDIFF(dd, -1, convert(datetime, @dbdate, 112)) % 7)+1;
值112是sql样式YYYYMMDD。
这是确定性的,因为datediff不接收字符串输入,如果要接收字符串,它将不再起作用,因为它内部将其转换为datetime对象。不确定的。
答案 7 :(得分:0)
尽管这很旧。评论简单的答案以帮助将来的读者。 @ liver-larson几乎是正确的。错误地将纪元时间0(1900年1月1日)设为星期日。实际上是星期一。
代码错误-https://stackoverflow.com/a/20481717/2012977
datediff(dd,0,[DateColumn]) % 7 + 1
更正
datediff(dd,-1,[DateColumn]) % 7 + 1
我喜欢这个答案,因为没有日期转换发生并且可以确定。
代码的单元测试。不幸的是,在撰写本文时SqlFiddle下降了。注意此处对列值进行硬编码。期望列为日期类型。
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
答案 8 :(得分:-1)
不确定您要找的是什么,但如果这是网站的一部分,请从http://php.net/manual/en/function.date.php
尝试此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;
}
答案 9 :(得分:-1)
星期几?你为什么不只使用DATEPART?
DATEPART(weekday, YEAR_DATE)
答案 10 :(得分:-1)
你不能只用以下的东西选择它:
SELECT DATENAME(dw, GETDATE());