目录

介绍

周默认开始日

设置周开始日

1.设置'DATEFIRST'

2.设置'DATEFIRST'并在任何逻辑操作后恢复为默认值

自定义助手函数

周函数

使用函数

参考


  • 下载源代码 - 1.6 KB

介绍

本文的目的是找到DATE/DATETIME给定DATETIME对象的周开始和结束。

我们会做什么:

  1. 检查SQL Server默认功能
  2. 探索其他选择和技巧
  3. 使用自定义功能

周默认开始日

默认情况下,SQL Server一周开始日期为星期日。在这里,我们正在为当前的DateTime填充周DATE/DATETIME范围。

DECLARE @dateTimeNow DATETIME = GETDATE();
SELECT [StartDate] = DATEADD(dd, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0)),[EndDate] = DATEADD(dd, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0));
SELECT [StartDateTime] = DATEADD(DAY, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow), 0)),[EndDateTime] = DATEADD(DAY, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow) + 1, 0)))

设置周开始日

在SQL Server中,有一个 @@DATEFIRST 函数,它返回当前的周开始日期(SET DATEFIRST的值)。要更改默认的周开始日,我们可以将任何周开始日设置为1-7 到DATEFIRST之间的值。

SELECT @@DATEFIRST;
SET DATEFIRST 7;     /*setting week start to 'Sunday'*/
  • @@DATEFIRST是会话的本地。我们可以通过在SQL Server Management Studio中打开不同的选项卡并在不同的选项卡中执行set / select代码来验证它。
  • DATEFIRST值变化会对DATEPART(WEEKDAY, )产生影响。

1.设置'DATEFIRST'

在这里,我们将周开始日设置为星期日

SET DATEFIRST 7;     /*setting week start to 'Sunday'*/
DECLARE @dateTimeNow DATETIME = GETDATE();
SELECT [StartDate] = DATEADD(dd, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0)),[EndDate] = DATEADD(dd, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0));
SELECT [StartDateTime] = DATEADD(DAY, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow), 0)),[EndDateTime] = DATEADD(DAY, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow) + 1, 0)))

2.设置'DATEFIRST'并在任何逻辑操作后恢复为默认值

如果我们需要在同一个查询/会话中使用多周开始日值,我们可以这样做:

  1. 备份当前 @@DATEFIRST
  2. 设置DATEFIRST预期的周开始日
  3. 做任何逻辑操作
  4. 操作后从备份重置DATEFIRST
DECLARE @dbDefaultWeekStart INTEGER = @@DATEFIRST; /*take backup of db default week start day*/
DECLARE @expectedWeekStart INTEGER = 6;            /*expected week start from 'Saturday'*/
SET DATEFIRST @expectedWeekStart;                  /*set week start day as expected*//*doing our calculation as needed*/
DECLARE @dateTimeNow DATETIME = GETDATE();
SELECT [StartDate] = DATEADD(dd, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0)),[EndDate] = DATEADD(dd, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0));
SELECT [StartDateTime] = DATEADD(DAY, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow), 0)),[EndDateTime] = DATEADD(DAY, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow) + 1, 0)))/*reset week start date to its default or as it was*/
SET DATEFIRST @dbDefaultWeekStart;

自定义助手函数

周函数

在这里,我们将创建一个星期辅助函数...

哪个会输入:

  • @weekStartDay INTEGER——是必需的,应该是1-7之间的任何一个
  • @dateTime DATETIME——是必需的
  • @weekPart VARCHAR(10)——是必需的,应该是('Start''Middle''End')之间的任何一个

并将输出:

  • 预期的周部分('Start''Middle''End')作为DateTime对象。
/*create function*/
IF OBJECT_ID(N'WeekPart', N'FN') IS NOT NULLDROP FUNCTION WeekPart;
GO
CREATE FUNCTION WeekPart(@weekStartDay INTEGER, @dateTime DATETIME, @weekPart VARCHAR(10))
RETURNS DATETIME
AS
BEGIN    /*validations*/IF @dateTime IS NULLBEGINRETURN @dateTime;ENDIF @weekStartDay NOT BETWEEN 1 AND 7BEGINRETURN CAST('week start day value should be BETWEEN 1 AND 7' AS INT);ENDIF @weekPart NOT IN('Start', 'Middle', 'End')BEGINRETURN CAST('week part should be IN(Start, Middle, End)' AS INT);END/*date to day number: https://docs.microsoft.com/en-us/sql/t-sql/statements/set-datefirst-transact-sql?view=sql-server-2017*/DECLARE @dayNumber INTEGER;SELECT @dayNumber =CASE DATENAME(WEEKDAY, @dateTime)WHEN 'Monday'    THEN 1WHEN 'Tuesday'    THEN 2WHEN 'Wednesday'THEN 3WHEN 'Thursday'    THEN 4WHEN 'Friday'    THEN 5WHEN 'Saturday'    THEN 6WHEN 'Sunday'    THEN 7END;/*calculate result*/DECLARE @difference INTEGER = -((7+@dayNumber-@weekStartDay)%7);DECLARE @startDateTime DATETIME = DATEADD(dd, @difference, @dateTime);DECLARE @resultDateTime DATETIME;SELECT @resultDateTime = CASE @weekPartWHEN 'Start'    THEN @startDateTimeWHEN 'Middle'    THEN DATEADD(dd, 3, @startDateTime)WHEN 'End'        THEN DATEADD(dd, 6, @startDateTime)ELSE @dateTimeEND;RETURN @resultDateTime;
END;

使用函数

让我们在查询中使用创建的函数,我们将星期六设置为星期开始日。如果需要,我们甚至可以将SQL Servers @@DATEFIRST值作为参数传递。

/*result*/
DECLARE @dateTimeNow DATETIME = GETDATE();
DECLARE @expectedWeekStart INTEGER;
SET @expectedWeekStart = 6;                   /*set 'Saturday', without changing db default*/
--SELECT @expectedWeekStart = @@DATEFIRST;    /*using db default*/SELECT [NowDate] = CAST(@dateTimeNow AS DATE),[WeekStartDate] = CAST(dbo.WeekPart(@expectedWeekStart, @dateTimeNow, 'start') AS DATE),[WeekMiddleDate] = CAST(dbo.WeekPart(@expectedWeekStart, @dateTimeNow, 'middle') AS DATE),[WeekEndDate] = CAST(dbo.WeekPart(@expectedWeekStart, @dateTimeNow, 'end') AS DATE);
SELECT [NowDate] = DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0),[WeekStartDateTime] = DATEADD(dd, DATEDIFF(dd, 0, _dbo.WeekPart(@expectedWeekStart, @dateTimeNow, 'start')), 0),[WeekMiddleDateTime] = DATEADD(dd, DATEDIFF(dd, 0, _dbo.WeekPart(@expectedWeekStart, @dateTimeNow, 'middle')), 0),[WeekEndDate] = DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, _dbo.WeekPart(@expectedWeekStart, @dateTimeNow, 'end')) + 1, 0));

参考

  • 周开始和结束:https://stackoverflow.com/a/1267176/2948523
  • @@ DATEFIRST日期编号:https://docs.microsoft.com/en-us/sql/t-sql/statements/set-datefirst-transact-sql?view=sql-server-2017
  • @@ DATEFIRST是本地会话:https://stackoverflow.com/questions/883127/sql-server-set-datefirst-scope
  • 查找日期名称: https://database.guide/3-ways-to-get-the-day-name-from-a-date-in-sql-server-t-sql/
  • 规范化一周的第一天:https://www.itprotoday.com/sql-server/normalizing-first-day-week

原文地址:https://www.codeproject.com/Tips/5161640/SQL-Server-Find-Week-Start-And-End-DateTime

SQL Server:查找周开始和结束日期时间相关推荐

  1. SQL Server(第二章) 字符串函数、日期时间函数、转换函数

    --1.CONCAT 函数:字符串连接(支持sql server2012 SQL规则 如果与NULL连接返回NILL) SELECT empid,CONCAT(firstname,lastname) ...

  2. SQL Server 查找统计信息的采样时间与采样比例

    SQL Server 查找统计信息的采样时间与采样比例 原文:SQL Server 查找统计信息的采样时间与采样比例 有时候我们会遇到,由于统计信息不准确导致优化器生成了一个错误的执行计划(或者这样表 ...

  3. sql server使用convert来取得datetime日期数据

    sql server使用convert来取得datetime日期数据,以下实例包含各种日期格式的转换 语句及查询结果: Select CONVERT(varchar(100), GETDATE(), ...

  4. Java:获取当前日期当前季度、上一季度开始结束日期时间

    获取当前时间的所在季度开始结束日期 /*** 计算某日期所在季度开始日期* 季度划分:1.2.3, 4.5.6, 7.8.9, 10.11.12*/public static Date getSeas ...

  5. android日历获取周,从android中的周数和年份获取周开始和结束日期

    您可以使用以下方法获取一周的第一个日期和结束日期 void getStartEndOFWeek(int enterWeek, int enterYear){ //enterWeek is week n ...

  6. 根据年月以及月中周次,获取该周开始,结束日期

    注意,是该月中的周次,一周最多有6周. <span style="background-color: rgb(102, 51, 255);">//获取周开始日期和结束日 ...

  7. mysql timediff 时间相减_leetcode题库-sql练习精讲系列--十、日期时间函数的使用

    这是一个系列文章,这个系列的理念是通过一道题,搞懂一类题.涵盖了SQL面试最常考的知识点.搞懂这些题,面试时工作中sql不可能有问题. 文章分为引入问题-完整解析-答案-leetcode题和答案-知识 ...

  8. 使用sql语句计算周次及起始日期

    最近在做周报填报的功能,其中需要算一下周次及起始日期.本打算用程序代码算一下的,但是感觉用sql更有意思,所以搜了一些相关的知识以及前人写的相关的sql语句,在此基础上进行了完善. 1.国际标准周日是 ...

  9. sql server取某个时间段内所有日期或者所有月份

    取所有月份: declare @begin datetime,@end datetime set @begin='2015-2-6' set @end='2015-12-2' declare @mon ...

最新文章

  1. BZOJ 3456: 城市规划 [多项式求逆元 DP]
  2. Spring的属性依赖检查
  3. rabbitmq 同步策略_RabbitMQ(三):消息持久化策略
  4. C语言实现支持增删查改的通讯录
  5. java标签组件命名_java编程规范之java命名规范
  6. oracle导出1000万数据,1000万条数据,最好用什么工具做,是sql,还是oracle,抑或vfp?...
  7. python 当前日期_python 当前时间获取方法
  8. Javascript实战应用篇(2):继续完善网页文本框系列(增加水印和提示)
  9. Elasticsearch-2-附面试题
  10. SpringCloud 微服务网关Gateway常用限流算法以及简单实现
  11. 开源并“免费”的Linux平台DAW——Ardour 4.0发布
  12. 中小企业安全路由器防火墙
  13. 【XBL 无法开机问题】【工位机调试】sdm660 XBL阶段,绕过电池在位检测,强制启动
  14. 你也可以找到好工作(三)大结局
  15. 关于numpy.take()用法
  16. python中slice是什么类型_在python中,slice是一个副本还是一个poin
  17. 微信公众号支付详细步骤(整理)
  18. bootstrap-table固定左侧列+表头和内容对齐
  19. 计算机基础知识【4】(08-08)
  20. 打印机监控软件开发外包

热门文章

  1. ae在哪里直接复制合成_AE模板里修改复制的合成如何不影响原先的合成?
  2. android 混淆方法名,android – 如何告诉Proguard混淆类名
  3. python中hub_PyHubWeekly | 第一期:Github上那些值得推荐的Python小工具
  4. 流量 起伏大_广西崇左的德天跨国大瀑布,一半是中国一半是越南,天下奇观!...
  5. 迁移python虚拟环境搭建_python虚拟环境virtualenv创建与迁移
  6. hashmap底层原理_周末自己动手撸一个 HashMap,美滋滋
  7. 手把手教你入侵网站修改数据_手把手教你使用Python抓取QQ音乐数据(第四弹)...
  8. 2021年四月上旬推荐文章
  9. 利用scp在windows和linux之间进行文件和文件夹的数据拷贝
  10. C语言assert关键字