SQL 服务器的 Epi-week query/method
Epi-week query/method for SQL Server
epi周的定义如下:
"The first epi week of the year ends, by definition, on the first Saturday of January, as long as it falls at least four days into the month. Each epi week begins on a Sunday and ends on a Saturday."
参考:1
我用服务器语言 (C#/Java) 实现了它们,但我的问题是 return 来自 SQL 服务器存储过程的 epi 周和 epi 年
我强烈建议您在数据库中创建 Calendar
table(如果您还没有的话)。
它是一个 table 每一天都有一行的时间足以满足您的需求。
向 table 添加一列 EpiWeek
并填充一次。然后在任何需要的地方使用它,而不是即时计算它。
日历 table 在许多领域都很有用,并有助于使用 SQL 基于集合的查询解决各种问题。 Calendar table 是 Numbers
table 的特例,也经常有用。
详细示例见:
Why should I consider using an auxiliary calendar table?
本文有一节是关于 ISO 周数的。我不确定 ISO Week 和 Epi Week 是否相同,但您可以查看 Aaron Bertrand 如何计算 ISO 周数的示例:
Many, many, many people are dissatisfied with the way SQL Server calculates week number. Its strange algorithm used in DATEPART(WEEK, <date>)
does not always yield the same number as the ISO standard, which dictates that week 1 is the first week with 4 days. To deal with that, we can borrow from Books Online and create the following function:
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
Then we can update the table:
UPDATE Calendar SET W = dbo.ISOWeek(dt)
另外,这里有几个关于 Numbers 的链接 table:
查找 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
epi周的定义如下:
"The first epi week of the year ends, by definition, on the first Saturday of January, as long as it falls at least four days into the month. Each epi week begins on a Sunday and ends on a Saturday."
参考:1
我用服务器语言 (C#/Java) 实现了它们,但我的问题是 return 来自 SQL 服务器存储过程的 epi 周和 epi 年
我强烈建议您在数据库中创建 Calendar
table(如果您还没有的话)。
它是一个 table 每一天都有一行的时间足以满足您的需求。
向 table 添加一列 EpiWeek
并填充一次。然后在任何需要的地方使用它,而不是即时计算它。
日历 table 在许多领域都很有用,并有助于使用 SQL 基于集合的查询解决各种问题。 Calendar table 是 Numbers
table 的特例,也经常有用。
详细示例见:
Why should I consider using an auxiliary calendar table?
本文有一节是关于 ISO 周数的。我不确定 ISO Week 和 Epi Week 是否相同,但您可以查看 Aaron Bertrand 如何计算 ISO 周数的示例:
Many, many, many people are dissatisfied with the way SQL Server calculates week number. Its strange algorithm used in
DATEPART(WEEK, <date>)
does not always yield the same number as the ISO standard, which dictates that week 1 is the first week with 4 days. To deal with that, we can borrow from Books Online and create the following function: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
Then we can update the table:
UPDATE Calendar SET W = dbo.ISOWeek(dt)
另外,这里有几个关于 Numbers 的链接 table:
查找 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