在 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. CSS文字过多显示省略号

    CSS文字过多显示省略号 /*-webkit-line-clamp用来限制在一个块元素显示的文本的行数*/ .dot1{ width: 100%; display: -webkit-box; -web ...

  2. 一本通1641【例 1】矩阵 A×B

    1641: [例 1]矩阵 A×B sol:矩阵乘法模板.三个for循环 #include <bits/stdc++.h> using namespace std; typedef lon ...

  3. c++/ boost 库常见错误及解决方法总结

    1. error LNK2019: 无法解析的外部符号 "class boost::system::error_category const & __cdecl boost::sys ...

  4. java虚拟机的内存划分

    为了提高运算效率,就对空间进行不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式. 一. 1.jvm的内存划分: 区域名称 作用 寄存器 给cpu使用,和我们开发无关 本地方法栈 jv ...

  5. BZOJ4078 WF2014Metal Processing Plant(二分答案+2-SAT)

    题面甚至没给范围,由数据可得n<=200.容易想到二分答案,暴力枚举某集合的价值,2-SATcheck一下即可.这样是O(n4logn)的. 2-SAT复杂度已经是下界,考虑如何优化枚举.稍微改 ...

  6. 洛谷 P4841 城市规划 解题报告

    P4841 城市规划 题意 n个有标号点的简单(无重边无自环)无向连通图数目. 输入输出格式 输入格式: 仅一行一个整数\(n(\le 130000)\) 输出格式: 仅一行一个整数, 为方案数 \( ...

  7. sadpairs

    #include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') using ...

  8. 让外部网络访问K8S service的四种方式

    本文基于kubernetes 1.5.2版本编写 kube-proxy+ClusterIP kubernetes版本大于或者等于1.2时,配置: 修改master的/etc/kubernetes/pr ...

  9. linux开启swap(磁盘缓存)操作

    转载 2014年04月26日 14:41:15 4470 由于工作需要,要帮助同事查看linux服务器的缓存开启情况,经过查找资料,可确定通过以下方法确定Linux磁盘缓存是否已开启. 1.命令行下执 ...

  10. Golang异常处理-panic与recover

    Golang异常处理-panic与recover 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在程序设计中,容错是相当重要的一部分工作,在 Go中它是通过错误处理来实现的,err ...