在SQL服务器上的一周

时间:2014-01-13 16:45:41

标签: sql-server tsql

如何使用T-SQL从SQL Server中的日期中提取年份和星期组合,并使其与MySQL yearweek结果匹配?

例如这些MySQL查询(Click here for MySQL SQL Fiddle):

SELECT yearweek('2013-12-31');
SELECT yearweek('2014-01-01');

这会为两个日期返回201352。这是预期的结果。

但是在SQL Server中......

  • datepart按照年度摘录的预期工作
  • 有时datepart不会返回iso_week
  • 的预期值

使用此T-SQL查询无法实现MySQL结果...

SELECT datepart(year, @dt) * 100 + datepart (iso_week, @dt);

(Click here for T-SQL SQL Fiddle)以上的MySQL查询的T-SQL版本:

SELECT datepart(year, '2013-12-31') * 100 + datepart (iso_week, '2013-12-31');
SELECT datepart(year, '2014-01-01') * 100 + datepart (iso_week, '2014-01-01');

第一个日期的结果为201352,第二个日期的结果为201401

但是,这不是预期的结果,因为......

  • 2014-01-01属于2013年的最后
  • 因此预期结果为201352

您是否有经验丰富的T-SQL开发人员知道如何提取给定日期的年/周并且与我在MySQL中看到的匹配?

我需要在星期一开始一周。这就是我使用iso_week的原因。无论如何,我已使用week测试了结果并发现了相同的问题。当预期201401时,此查询也会生成201352

SELECT datepart(year, '2014-01-01') * 100 + datepart (week, '2014-01-01');

4 个答案:

答案 0 :(得分:2)

如果您查看http://msdn.microsoft.com/en-us/library/ms174420.aspx处的ISO_Week日期部分定义,您会看到以下内容:

  

ISO 8601包括ISO周日期系统,一个编号系统   周。每周与周四的年份相关联   发生...

     

不同国家/地区的编号系统可能不符合   符合ISO标准。

2014年1月1日是星期三; 2014年1月2日是今年的第一个星期四,因此是2014年第1周(根据ISO 8601)。

此外,查看yearweekweek的MySQL定义,有几种模式选项(http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_week

所以,我认为你必须为自己想要的周计数规则编写自己的yearweek函数:

CREATE FUNCTION dbo.yearweek(@date date)
RETURNS INT
as
 begin
    set @date = dateadd(dd,-datepart(dw,@date)+1, @date)

    return datepart(year,@date)*100 + datepart(week,@date)
 end
go

select dbo.yearweek('2013-12-31'), dbo.yearweek('2014-01-01')

注意:我尚未对此代码进行全面测试,但我不确定您的要求是什么。这仅仅是您需要遵循的流程类型的示例。

答案 1 :(得分:0)

我认为这是因为您使用“ISO_WEEK”作为日期部分

在此处查看“ISO_WEEK datepart”下的说明:http://msdn.microsoft.com/en-us/library/ms174420.aspx

使用“WEEK”可能会获得所需的结果

答案 2 :(得分:0)

要提取YEAR,MONTH或DAY,您只需使用YEAR,MONTH和DAY功能,如下面的示例所示。对于任何其他部分,您必须使用DATEPART函数read here获取可以传递给DATEPART函数的详细参数列表。

SELECT YEAR(GETDATE()) AS [YEAR]
       , DATEPART(WEEK, GETDATE()) [Week]

<强>更新

SELECT CAST(YEAR(GETDATE()) AS VARCHAR(4))  +'-' 
        +   CAST(DATEPART(WEEK, GETDATE()) AS VARCHAR(2)) 

答案 3 :(得分:0)

在我看来,你想要的是基于上周一的周数。它是否正确?如果是这样的话,iso_week对你没用,因为它基于本周的星期四。

要根据上周一获得年份和周数,我认为您需要以下内容。

set datefirst 1 ;

select
    SomeDate ,
    datename( weekday, SomeDate ) as [WeekdayName] , 
    datepart( weekday, SomeDate ) as [Weekday] , 
    datepart( week, SomeDate ) as [Week] ,
    datepart( iso_week, SomeDate ) as [ISO_week] ,
    dateadd( day, -( datepart( weekday, SomeDate ) - 1 ), SomeDate ) as [PreviousMonday] ,
    datepart( year, dateadd( day, -( datepart( weekday, SomeDate ) - 1 ), SomeDate ) ) as [MondayYear] ,
    datepart( week, dateadd( day, -( datepart( weekday, SomeDate ) - 1 ), SomeDate ) ) as [MondayWeek] 
from 
    dbo.DateDemo 
order by
    SomeDate ;

简化样本输出如下。

SomeDate    PreviousMonday  MondayYear  MondayWeek
2013-12-25  2013-12-23  2013    52
2013-12-26  2013-12-23  2013    52
2013-12-27  2013-12-23  2013    52
2013-12-28  2013-12-23  2013    52
2013-12-29  2013-12-23  2013    52
2013-12-30  2013-12-30  2013    53
2013-12-31  2013-12-30  2013    53
2014-01-01  2013-12-30  2013    53
2014-01-02  2013-12-30  2013    53
2014-01-03  2013-12-30  2013    53
2014-01-04  2013-12-30  2013    53
2014-01-05  2013-12-30  2013    53
2014-01-06  2014-01-06  2014    2