SQL Server的Epi周查询/方法

时间:2017-09-07 02:01:26

标签: sql sql-server datepart

epi-week的定义如下:

"根据定义,一年中的第一个epi周在1月的第一个星期六结束,只要它在该月至少下降四天。每个epi周从星期日开始,到星期六结束。"

参考:1

我用服务器语言(C#/ Java)实现它们但我的问题是从SQL Server存储过程返回epi周和epi年

2 个答案:

答案 0 :(得分:2)

我强烈建议您在数据库中创建一个Calendar表,如果您还没有。

这是一个表格,每个时段都有一行,足以满足您的需求。

将一列EpiWeek添加到此表中并填充一次。然后在任何需要的地方使用,而不是动态计算。

日历表在许多方面都很有用,有助于使用基于SQL集的查询解决各种问题。日历表是Numbers表的一个特例,它通常也很有用。

有关详细示例,请参阅:

Why should I consider using an auxiliary calendar table?

本文有一个关于ISO周数的部分。我不确定ISO周和Epi周是否相同,但您可以看到Aaron Bertrand如何计算ISO周数的示例:

  

很多很多人对SQL Server计算周数的方式不满意。它在DATEPART(WEEK, <date>)中使用的奇怪算法并不总是产生与ISO标准相同的数字,这标志着第1周是第4周的第一周。为了解决这个问题,我们可以借阅联机丛书并创建以下功能:

CREATE FUNCTION dbo.ISOWeek 
( 
    @dt SMALLDATETIME 
) 
RETURNS TINYINT 
AS 
BEGIN 
    DECLARE @ISOweek TINYINT 

    SET @ISOweek = DATEPART(WEEK,@dt)+1 
        -DATEPART(WEEK,RTRIM(YEAR(@dt))+'0104') 

    IF @ISOweek = 0 
    BEGIN 
        SET @ISOweek = dbo.ISOweek 
        ( 
            RTRIM(YEAR(@dt)-1)+'12'+RTRIM(24+DAY(@dt)) 
        ) + 1 
    END 

    IF MONTH(@dt) = 12 AND DAY(@dt)-DATEPART(DW,@dt) >= 28 
    BEGIN 
        SET @ISOweek=1 
    END 

    RETURN(@ISOweek) 
END 
GO
     

然后我们可以更新表格:

UPDATE Calendar SET W = dbo.ISOWeek(dt)

此外,这里有几个关于Numbers表的链接:

You REQUIRE a Numbers table!

Generate a set or sequence without loops

答案 1 :(得分:2)

查找EpiWeek:

 CREATE FUNCTION [dbo].[EPIWeek] 
( 
    @Date SMALLDATETIME 
) 
RETURNS TINYINT 
AS 
BEGIN 
    DECLARE @EPIWeek TINYINT 

    --Fix first epi week (i.e if 0401 of year falls in first week, then it will give perfect start epiweek)
    SET @EPIWeek = DATEPART(WEEK,@Date)+1 - DATEPART(WEEK,RTRIM(YEAR(@Date))+'0104') 
    --if 0401 of year falls in second week, then change to epiweek of last year
    IF @EPIWeek = 0 
    BEGIN 
        SET @EPIWeek = dbo.EPIWeek(RTRIM(YEAR(@Date)-1)+'1231')
    END 

    --Fix last epi week (ie. If any date after 2812 falls below wednesday, then it is first epiweek of next year)
    IF MONTH(@Date) = 12 AND DAY(@Date)-DATEPART(DW,@Date) >= 28 
    BEGIN 
        SET @EPIWeek=1 
    END 

    RETURN(@EPIWeek) 
END 

寻找EpiYear:

CREATE FUNCTION [dbo].[EPIYear] 
( 
    @Date DATETIME
) 
RETURNS INT
AS
BEGIN
  DECLARE @EPIYear INT = DATEPART(YEAR, @Date);

  -- WHEN January 1-3 may belong to the previous year
  IF (DATEPART(MONTH, @DATE) = 1 AND dbo.EPIWeek(@DATE) > 50)
    SET @EPIYear = @EPIYear - 1;

  -- WHEN December 29-31 may belong to the next year
  IF (DATEPART(MONTH, @DATE) = 12 AND dbo.EPIWeek(@DATE) < 45)
    SET @EPIYear = @EPIYear + 1;

  RETURN @EPIYear;

END