在 SQL Server 中默认情况下,每周的开始都是从周日开始算起的,如果默认星期一呢?

这里有三种方式可以解决这个问题:
一:直接通过 SET DATEFIRST VALUE 来更改重新生成新的 DimDate,然后每次需要单独计算 Week Number 的时候根据 Date Key 关联一下就可以了,但这样就需要不断 JOIN DimDate,每一条记录都要 LookUp 一遍
二:在存储过程中需要使用到  Week Number 的时候,就先设置一下 SET DATEFIRST 然后在使用 DATEPART() 函数来获取 Week Number
SET DATEFIRST 1   --定义日期周一开始

三:直接写一个函数,每次调用一下就可以了

SELECT @@DATEFIRST  --7
SELECT DATENAME(WEEK,'2013-12-31') AS WeekName -- 53
SELECT DATENAME(WEEK,'2014-01-01') AS WeekName -- 1
SELECT DATENAME(WEEK,'2014-01-05') AS WeekName -- 2

代码:

1.创建表:

IF OBJECT_ID('DimDateStartWithMonday','U') IS NOT NULL
DROP TABLE DimDateStartWithMonday
GO CREATE TABLE DimDateStartWithMonday
(
DateKey INT PRIMARY KEY,
FullDate DATE NOT NULL,
[DateName] NVARCHAR(20),
DayNumberOfWeek TINYINT NOT NULL,
DayNameOfWeek NVARCHAR(10) NOT NULL,
DayNumberOfMonth TINYINT NOT NULL,
DayNumberOfYear SMALLINT NOT NULL,
WeekNumberOfYear TINYINT NOT NULL,
EnglishMonthName NVARCHAR(10) NOT NULL,
MonthNumberOfYear TINYINT NOT NULL,
CalendarQuarter TINYINT NOT NULL,
CalendarSemester TINYINT NOT NULL,
CalendarYear SMALLINT NOT NULL
)

2.插入值

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME SELECT @StartDate = '2001-01-01',
@EndDate = '2035-12-31' WHILE(@StartDate<+@EndDate)
BEGIN
INSERT INTO DimDateStartWithMonday
(
DateKey,
FullDate,
[DateName],
DayNumberOfWeek,
DayNameOfWeek,
DayNumberOfMonth,
DayNumberOfYear,
WeekNumberOfYear,
EnglishMonthName,
MonthNumberOfYear,
CalendarQuarter,
CalendarSemester,
CalendarYear
)
SELECT CAST(CONVERT(VARCHAR(8),@StartDate,112) AS INT) AS DateKey,
CONVERT(VARCHAR(10), @StartDate,20) AS FullDate,
CONVERT(VARCHAR(20), @StartDate,106) AS [DateName],
DATEPART(DW,@StartDate) AS DayNumberOfWeek,
DATENAME(DW,@StartDate) AS DayNameOfWeek,
DATENAME(DD,@StartDate) AS [DayOfMonth],
DATENAME(DY,@StartDate) AS [DayOfYear],
DATEPART(WW,@StartDate) AS WeekNumberOfYear,
DATENAME(MM,@StartDate) AS EnglishMonthName,
DATEPART(MM,@StartDate) AS MonthNumberOfYear,
DATEPART(QQ,@StartDate) AS CalendarQuarter,
CASE WHEN DATEPART(MM,@StartDate) BETWEEN 1 AND 6
THEN 1
ELSE 2
END AS CalendarSemester,
DATEPART(YY,@StartDate) AS CalendarYear
SET @StartDate = @StartDate + 1
END

3.自定义函数

	   IF OBJECT_ID('ETLWORK_GETWEEKNUMBER','FN') IS NOT NULL
DROP FUNCTION ETLWORK_GETWEEKNUMBER
GO CREATE FUNCTION ETLWORK_GETWEEKNUMBER(@DATE DATETIME)
RETURNS INTEGER
AS
BEGIN
DECLARE @FIRST_DATE_OF_YEAR DATETIME = DATEADD(YYYY,DATEDIFF(YYYY,0,@DATE),0) DECLARE @WEEK_NUMBER INTEGER -- 如果当前时间是当前年的第一天
IF @DATE = @FIRST_DATE_OF_YEAR
SET @WEEK_NUMBER = 1
-- 星期天是年第一天的情况
ELSE IF (DATEPART(WEEKDAY,@DATE) = 1 AND DATEDIFF(DAYOFYEAR,@FIRST_DATE_OF_YEAR,@DATE)/7 + 1 = DATEPART(WEEK,@DATE))
SET @WEEK_NUMBER = DATEPART(WEEK,@DATE)
-- 星期天不是年第一天的情况
ELSE IF (DATEPART(WEEKDAY,@DATE) = 1 AND DATEDIFF(DAYOFYEAR,@FIRST_DATE_OF_YEAR,@DATE)/7 + 1 <> DATEPART(WEEK,@DATE))
SET @WEEK_NUMBER = DATEPART(WEEK,@DATE) - 1
-- 如果当前天的上一个周日小于年第一天
ELSE IF DATEADD(DAY,-1,DATEADD(WK,DATEDIFF(WK,0,@DATE),0)) < @FIRST_DATE_OF_YEAR
SET @WEEK_NUMBER = 1
-- 当前天前面的一个周日正好是以周日为开始年的 7 倍的天数
ELSE IF DATEDIFF(DAYOFYEAR,@FIRST_DATE_OF_YEAR,DATEADD(DAY,-1,DATEADD(WK,DATEDIFF(WK,0,@DATE),0) ))/7 + 1 = DATEPART(WEEK,@DATE)
SET @WEEK_NUMBER = DATEPART(WEEK,@DATE) + 1
ELSE
SET @WEEK_NUMBER = DATEPART(WEEK,@DATE) RETURN @WEEK_NUMBER
END

测试:

DECLARE @DATE DATETIME = '2017-01-02'
DECLARE @FIRST_DATE_OF_YEAR DATETIME = DATEADD(YYYY,DATEDIFF(YYYY,0,@DATE),0) SELECT DATEPART(WEEK,@DATE), -- 一年中的周数,默认以周日开始
DATEADD(WK,DATEDIFF(WK,0,@DATE),0), -- 当前周的周一,默认从周日开始,但是仍然找周一
DATEADD(DAY,-1,DATEADD(WK,DATEDIFF(WK,0,@DATE),0)), -- 当前周先找周一,然后往前一天找到周日
DATEDIFF(DAYOFYEAR,@FIRST_DATE_OF_YEAR,DATEADD(DAY,-1,DATEADD(WK,DATEDIFF(WK,0,@DATE),0))), -- 当前天离年第一天的间隔
DATEDIFF(DAYOFYEAR,@FIRST_DATE_OF_YEAR,DATEADD(DAY,-1,DATEADD(WK,DATEDIFF(WK,0,@DATE),0) ))/7 + 1 -- 按天计算的周数

SqlServer中 SET DATEFIRST更改的更多相关文章

  1. SQLSERVER中的假脱机spool

    SQLSERVER中的假脱机spool 我发现网上对于假脱机的解释都非常零散,究竟假脱机是什么? 这几天在家里研究了一下,收集了很多网上的资料 假脱机是中文的翻译,而英文的名字叫做 spool 在徐老 ...

  2. (转)笔记320 SQLSERVER中的加密函数 2013-7-11

    1 --SQLSERVER中的加密函数 2013-7-11 2 ENCRYPTBYASYMKEY() --非对称密钥 3 ENCRYPTBYCERT() --证书加密 4 ENCRYPTBYKEY() ...

  3. SqlServer 中如何查看某一个Sql语句是复用了执行计划,还是重新生成了执行计划

    我们知道SqlServer的查询优化器会将所执行的Sql语句的执行计划作缓存,如果后续查询可以复用缓存中的执行计划,那么SqlServer就会为后续查询复用执行计划而不是重新生成一个新的执行计划,因为 ...

  4. SqlServer中使用Select语句给变量赋值的时候需要注意的一个问题

    我们知道在SqlServer中可以用Select语句给变量赋值,比如如下语句就为int类型的变量@id赋值 ; select @id=id from ( as id union all as id u ...

  5. Sqlserver中存储过程,触发器,自定义函数

    Sqlserver中存储过程,触发器,自定义函数: 1. 触发器:是针对数据库表或数据库的特殊存储过程,在某些行为发生的时候就会被激活 触发器的分类: DML触发器:发生在数据操作语言执行时触发执行的 ...

  6. SQL点滴18—SqlServer中的merge操作,相当地风骚

    原文:SQL点滴18-SqlServer中的merge操作,相当地风骚 今天在一个存储过程中看见了merge这个关键字,第一个想法是,这个是配置管理中的概念吗,把相邻两次的更改合并到一起.后来在tec ...

  7. SQLServer 中发布与订阅

    在对数据库做迁移的时候,会有很多方法,用存储过程,job,也可以用开源工具kettle,那么今天这些天变接触到了一种新的方法,就是SqlServer中自带的发布与订阅. 首先说明一下数据复制的流程.如 ...

  8. 【SqlServer】解析SqlServer中的事务

    目录结构: contents structure [+] 事务是什么 控制事务 数据并发访问产生的影响 事务的隔离级别 锁 NOLOCK.HOLDLOCK.UPDLOCK 死锁分析 在这篇Blog中, ...

  9. SQLSERVER中的资源调控器

    SQLSERVER中的资源调控器 转载自: http://wenku.baidu.com/view/0d92380cf78a6529647d5375.html http://www.cnblogs.c ...

随机推荐

  1. 【跨域】jsonp跨域实现方法

    封装原生jsonp: 以跨域调取豆瓣电影最热榜单为例: function $jsonp(url,data,callback){ var funcName = 'jsonp_cb' + Math.ran ...

  2. 【设计模式】—— 迭代模式Iterator

    前言:[模式总览]——————————by xingoo 模式意图 提供一个方法按顺序遍历一个集合内的元素,而又不需要暴露该对象的内部表示. 应用场景 1 访问一个聚合的对象,而不需要暴露对象的内部表 ...

  3. Semi synchronous replication

    目标 主库宕机不丢数据(Master Failover without data loss) facebook有两篇不错的文章: 2015/01: performance-issues-and-fix ...

  4. AtCoder Grand Contest 006

    AtCoder Grand Contest 006 吐槽 这套题要改个名字,叫神仙结论题大赛 A - Prefix and Suffix 翻译 给定两个串,求满足前缀是\(S\),后缀是\(T\),并 ...

  5. 洛谷 P4112 [HEOI2015]最短不公共子串 解题报告

    P4112 [HEOI2015]最短不公共子串 题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的"子串"指的是它的连续的一段,例如bcd是 ...

  6. 部署kube-prometheus,添加邮件报警

    这个项目出自coreos,已经存在很久了,第一次尝试的时候还很简陋,现在完善了很多. 项目提供了一键部署脚本,跑起来并不难,不过个人感觉要真正掌握并灵活使用并不是很容易. kube version: ...

  7. java保留两位小数和js保留两位小数一致性研究

    一.java保留两位小数方式 public static void main(String[] args) { System.out.println("=======DecimalForma ...

  8. C&C++图形图像处理开源库

    Google三维APIO3D O3D 是一个开源的 WebAPI 用来在浏览器上创建界面丰富的交互式的 3D 应用程序.这是一种基于网页的可控3D标准.此格式期望真正的基于浏览器,独立于操作系统之外, ...

  9. 图像处理之生成ColorBar

    1 colorBar介绍 colorBar主要是指一些图像处理中使用的常见纯色或者渐变色条.colorBar用途可作为测试样图来验证某些图像算法的效果,从而避免图像内容或者硬件对图像的干扰,使图像算法 ...

  10. 用HashSet存储不重复的对象

    直接进入主题,先来创建一个类:Bean public class Bean { private int id; private String name; public Bean() { super() ...