SQL查询帮助:以非临时方式转换日期
我有一个带有"日期"列的表,我想执行以下查询:
如果日期是星期一,星期二,星期三或者星期四,则显示的日期应上移1天,如
DATEADD(day, 1, [Date])
另一方面,如果是星期五,则显示的日期应增加3天(即,它变成下一个星期一)。
如何在SELECT语句中执行此操作?如
SELECT somewayofdoingthis([Date]) FROM myTable
(这是SQL Server2000。)
解决方案
我们需要创建一个SQL函数来为我们执行此转换。
听起来像CASE表达式。我不知道SQL Server的适当数据操作,但基本上它看起来像这样:
CASE WHEN [Date] is a Friday THEN DATEADD( day, 3, [Date] ) ELSE DATEADD( day, 1, [Date] ) END
如果要检查周末,可以在ELSE之前添加其他WHEN子句。
这是我的头上的事情,可以清除它,但可以以此为起点:
select case when DATENAME(dw, [date]) = 'Monday' then DATEADD(dw, 1, [Date]) when DATENAME(dw, [date]) = 'Tuesday' then DATEADD(dw, 1, [Date]) when DATENAME(dw, [date]) = 'Wednesday' then DATEADD(dw, 1, [Date]) when DATENAME(dw, [date]) = 'Thursday' then DATEADD(dw, 1, [Date]) when DATENAME(dw, [date]) = 'Friday' then DATEADD(dw, 3, [Date]) end as nextDay ...
我们可以使用此:
select dayname,newdayname = CASE dayname WHEN 'Monday' THEN 'Tuesday' WHEN 'Tuesday' THEN 'Wednesday' WHEN 'Wednesday' THEN 'Thursday' WHEN 'Thursday' THEN 'Friday' WHEN 'Friday' THEN 'Monday' WHEN 'Saturday' THEN 'Monday' WHEN 'Sunday' THEN 'Monday' END FROM UDO_DAYS
results: Monday Tuesday Tuesday Wednesday Wednesday Thursday Thursday Friday Friday Monday Saturday Monday Sunday Monday table data: Monday Tuesday Wednesday Thursday Friday Saturday Sunday
这就是我要怎么做。如果我们要在其他地方使用此功能,我建议我们使用上述功能。
CASE WHEN DATEPART(dw, [Date]) IN (2,3,4,5) THEN DATEADD(d, 1, [Date]) WHEN DATEPART(dw, [Date]) = 6 THEN DATEADD(d, 3, [Date]) ELSE [Date] END AS [ConvertedDate]
CREATE FUNCTION dbo.GetNextWDay(@Day datetime) RETURNS DATETIME AS BEGIN DECLARE @ReturnDate DateTime set @ReturnDate = dateadd(dd, 1, @Day) if (select datename(@ReturnDate))) = 'Saturday' set @ReturnDate = dateadd(dd, 2, @ReturnDate) if (select datename(@ReturnDate) = 'Sunday' set @ReturnDate = dateadd(dd, 1, @ReturnDate) RETURN @ReturnDate END
查找CASE语句和DATEPART语句。我们将需要在DATEPART中使用dw参数,以获取代表星期几的整数。
尝试
select case when datepart(dw,[Date]) between 2 and 5 then DATEADD(dd, 1, [Date]) when datepart(dw,[Date]) = 6 then DATEADD(dd, 3, [Date]) else [Date] end as [Date]
create table #dates (dt datetime) insert into #dates (dt) values ('1/1/2001') insert into #dates (dt) values ('1/2/2001') insert into #dates (dt) values ('1/3/2001') insert into #dates (dt) values ('1/4/2001') insert into #dates (dt) values ('1/5/2001') select dt, day(dt), dateadd(dd,1,dt) from #dates where day(dt) between 1 and 4 union all select dt, day(dt), dateadd(dd,3,dt) from #dates where day(dt) = 5 drop table #dates
我假设我们也希望星期六和星期日转移到下一个星期一。如果不是这种情况,请从(1,2,3,4,5)中取出1并删除最后一个when子句。
case --Sunday thru Thursday are shifted forward 1 day when datepart(weekday, [Date]) in (1,2,3,4,5) then dateadd(day, 1, [Date]) --Friday is shifted forward to Monday when datepart(weekday, [Date]) = 6 then dateadd(day, 3, [Date]) --Saturday is shifted forward to Monday when datepart(weekday, [Date]) = 7 then dateadd(day, 2, [Date]) end
我们也可以在一行中完成此操作:
select dateadd(day, 1 + (datepart(weekday, [Date])/6) * (8-datepart(weekday, [Date])), [Date])
这与Brian的代码大同小异,但由于parens不匹配而无法编译,因此我将IF更改为不包含选择内容。重要的是要注意,我们在这里使用DateNAME而不是datePART,因为datePART取决于SET DATEFIRST设置的值,SET DATEFIRST设置一周的第一天。
CREATE FUNCTION dbo.GetNextWDay(@Day datetime) RETURNS DATETIME AS BEGIN DECLARE @ReturnDate DateTime set @ReturnDate = dateadd(dd, 1, @Day) if datename(dw, @ReturnDate) = 'Saturday' set @ReturnDate = dateadd(dd, 2, @ReturnDate) if datename(dw, @ReturnDate) = 'Sunday' set @ReturnDate = dateadd(dd, 1, @ReturnDate) RETURN @ReturnDate END
如何从数据仓库人员获取页面并制作表格。用DW术语来说,这将是一个日期维度。标准日期维度将具有诸如日期的各种名称(" MON"," Monday"," August 22,1998")或者诸如月末和月初之类的指示符。但是,我们也可以使用仅在环境中有意义的列。
例如,根据问题,下一个工作日列可能会指向相关日期的键。这样,我们可以进一步自定义它,以考虑假期或者其他非工作日。
DW员工坚决使用无意义的键(也就是说,不要只使用截断的日期作为键,而要使用生成的键),但是我们可以自己决定。
Date Dimension Toolkit包含用于在各种DBMS中生成我们自己的表的代码,并且具有用于数年日期的CSV数据。