DATEPART:当不能使用 SET DATEFIRST 时指定一周的第一天
DATEPART: specifying first day of week when SET DATEFIRST cannot be used
我正在 ReportServer(动态列表类型)中创建一些报告,其中之一是从 SQL 服务器检索过去一周事件的信息。
在 SSMS 中,这很简单,我通过
获得了所需的信息(按时间)
... WHERE DATEPART(week, event_date) = DATEPART(week, DATEADD(d, -5, GETDATE()))
前面有一个
SET DATEFIRST 1;
声明以便将星期一设置为一周的第一天。
不幸的是,ReportServer 不接受 SET DATEFIRST
语句作为查询的一部分,因此在将其删除后,返回的数据范围是星期日到星期六,而不是星期一到星期日。我无法对数据库(或服务器)进行全局更改。
我该如何解决这个问题?
您可以使用 @@DATEFIRST
来尝试一下。这是一个系统变量,您无需在 inline/ad-hoc 查询中进行任何声明或设置即可使用:
--这是星期天
DECLARE @OneSunday DATE='20190929';
--你的说法return在不同的文化中是不同的
SET LANGUAGE ENGLISH;
SELECT DATEPART(week, @OneSunday); --<-- returns 40
SELECT @@DATEFIRST; --<-- returns 7
SET LANGUAGE GERMAN;
SELECT DATEPART(week, @OneSunday); --<-- returns 39
SELECT @@DATEFIRST; --<-- returns 1
如您所见,系统变量@@DATEFIRST
反映了当天的索引,这是由文化设置的。您可以将它用于一些校正算法。
SET LANGUAGE ENGLISH;
SELECT DATEPART(week, DATEADD(DAY,(@@DATEFIRST % 7),@OneSunday));
SET LANGUAGE GERMAN;
SELECT DATEPART(week, DATEADD(DAY,(@@DATEFIRST % 7),@OneSunday));
现在都是return40.
我使用 % 7
得到一个 0
,其中 @@DATEFIRST
return 是 7
。
计算所需的一周第一天,然后在 where
子句中使用周日期范围,例如
declare @FirstDayOfWeek date, @Now date = getdate();
select @FirstDayOfWeek = dateadd(day, -1*(case when datepart(weekday, @Now) > 1 then datepart(weekday, @Now)-2 else 6 end), @Now);
select *
from dbo.MyTable
where event_date >= @FirstDayOfWeek and event_date < dateadd(week, 1, @FirstDayOfWeek);
当然您也可以将计算嵌入到查询中,例如
select *
from dbo.MyTable
cross join (
select dateadd(day, -1*(case when datepart(weekday, getdate()) > 1 then datepart(weekday, getdate())-2 else 6 end), getdate()) FirstDayOfWeek
) D
where event_date >= D.FirstDayOfWeek and event_date < dateadd(week, 1, D.FirstDayOfWeek);
注意:您可以将日期计算复制到 where
子句中并避免使用 join
,但我不喜欢重复计算。
因为您想要以 Monday
开始的一周,所以您使用 Monday
的参考日期,例如 1900-01-01
并计算一周的开始和结束日期
begin_of_week = dateadd(day, datediff(day, '1900-01-01', [date]) / 7 * 7, '1900-01-01')
并获取周末日期,
end_of_week = dateadd(day, datediff(day, '1900-01-01', [date]) / 7 * 7 + 7, '1989-12-31')
所以把它放到你的查询中(我假设你的 event_date 可能包含时间部分,因此,上面的条件是 less than
<
)
WHERE event_date >= dateadd(day, datediff(day, '1900-01-01', getdate()) / 7 * 7, '1900-01-01')
AND event_date < dateadd(day, datediff(day, '1900-01-01', getdate()) / 7 * 7 + 7, '1900-01-01')
我正在 ReportServer(动态列表类型)中创建一些报告,其中之一是从 SQL 服务器检索过去一周事件的信息。
在 SSMS 中,这很简单,我通过
获得了所需的信息(按时间)... WHERE DATEPART(week, event_date) = DATEPART(week, DATEADD(d, -5, GETDATE()))
前面有一个
SET DATEFIRST 1;
声明以便将星期一设置为一周的第一天。
不幸的是,ReportServer 不接受 SET DATEFIRST
语句作为查询的一部分,因此在将其删除后,返回的数据范围是星期日到星期六,而不是星期一到星期日。我无法对数据库(或服务器)进行全局更改。
我该如何解决这个问题?
您可以使用 @@DATEFIRST
来尝试一下。这是一个系统变量,您无需在 inline/ad-hoc 查询中进行任何声明或设置即可使用:
--这是星期天
DECLARE @OneSunday DATE='20190929';
--你的说法return在不同的文化中是不同的
SET LANGUAGE ENGLISH;
SELECT DATEPART(week, @OneSunday); --<-- returns 40
SELECT @@DATEFIRST; --<-- returns 7
SET LANGUAGE GERMAN;
SELECT DATEPART(week, @OneSunday); --<-- returns 39
SELECT @@DATEFIRST; --<-- returns 1
如您所见,系统变量@@DATEFIRST
反映了当天的索引,这是由文化设置的。您可以将它用于一些校正算法。
SET LANGUAGE ENGLISH;
SELECT DATEPART(week, DATEADD(DAY,(@@DATEFIRST % 7),@OneSunday));
SET LANGUAGE GERMAN;
SELECT DATEPART(week, DATEADD(DAY,(@@DATEFIRST % 7),@OneSunday));
现在都是return40.
我使用 % 7
得到一个 0
,其中 @@DATEFIRST
return 是 7
。
计算所需的一周第一天,然后在 where
子句中使用周日期范围,例如
declare @FirstDayOfWeek date, @Now date = getdate();
select @FirstDayOfWeek = dateadd(day, -1*(case when datepart(weekday, @Now) > 1 then datepart(weekday, @Now)-2 else 6 end), @Now);
select *
from dbo.MyTable
where event_date >= @FirstDayOfWeek and event_date < dateadd(week, 1, @FirstDayOfWeek);
当然您也可以将计算嵌入到查询中,例如
select *
from dbo.MyTable
cross join (
select dateadd(day, -1*(case when datepart(weekday, getdate()) > 1 then datepart(weekday, getdate())-2 else 6 end), getdate()) FirstDayOfWeek
) D
where event_date >= D.FirstDayOfWeek and event_date < dateadd(week, 1, D.FirstDayOfWeek);
注意:您可以将日期计算复制到 where
子句中并避免使用 join
,但我不喜欢重复计算。
因为您想要以 Monday
开始的一周,所以您使用 Monday
的参考日期,例如 1900-01-01
并计算一周的开始和结束日期
begin_of_week = dateadd(day, datediff(day, '1900-01-01', [date]) / 7 * 7, '1900-01-01')
并获取周末日期,
end_of_week = dateadd(day, datediff(day, '1900-01-01', [date]) / 7 * 7 + 7, '1989-12-31')
所以把它放到你的查询中(我假设你的 event_date 可能包含时间部分,因此,上面的条件是 less than
<
)
WHERE event_date >= dateadd(day, datediff(day, '1900-01-01', getdate()) / 7 * 7, '1900-01-01')
AND event_date < dateadd(day, datediff(day, '1900-01-01', getdate()) / 7 * 7 + 7, '1900-01-01')