SQL DatePart 反映会计年度的周、年

SQL DatePart Week, year to reflect fiscal year

我目前有一份报告使用 DATEPART 到 return 'car' 被 return 编辑的那一周。但是,我为财政年度工作的业务从一年的第一个星期日开始(这个实例从 03/01/2016 开始就是第 1 周)。但是,使用 SQL 'DATEPART wk' 会 return 这个日期是第 2 周:

使用 DATEPART(周、年等)的当前结果:

CarTitle      ReturnDate      Year       Week       
Car 1         30/12/2015      2015        53
Car 2         02/01/2016      2016        1
Car 3         03/01/2016      2016        2
Car 4         05/01/2016      2016        2
Car 5         10/01/2016      2016        3
Car 6         17/01/2016      2016        4

预期结果示例:

CarTitle      ReturnDate      Year       Week       
Car 1         30/12/2015      2015        53
Car 2         02/01/2016      2015        53
Car 3         03/01/2016      2016        1
Car 4         05/01/2016      2016        1
Car 5         10/01/2016      2016        2
Car 6         17/01/2016      2016        3

我可以用下面的方法计算这个 SQL:

SELECT
    CarTitle,
    DATEPART(ISO_WEEK, DATEADD(day, 1, ReturnDate))
FROM
    dbo.My_Table

但是,这取决于您的本地化设置(考虑到您表达日期的方式,这可能与我的不同)以及您是否在整个系统中使用此代码然后业务决定改变它计算周数的方法,那么你最终可能会遇到一个大的重构问题。

对于这种事情,我更喜欢使用日历 table:

CREATE TABLE dbo.Calendar (
    calendar_date    DATE        NOT NULL,
    week_number      SMALLINT    NOT NULL,
    is_holiday       BIT         NOT NULL,
    name             VARCHAR(30) NOT NULL,  -- i.e. 'January 6th, 2016'
    CONSTRAINT PK_Calendar PRIMARY KEY CLUSTERED (calendar_date)
)

您可以根据需要扩展 table,例如,如果会计部门使用与其他部门不同的年度周定义,则可以通过添加另一列轻松实现。然后,这会使您的查询成为一个简单的连接以获取周数:

SELECT
    MT.CarTitle,
    MT.ReturnDate,
    CAL.week_number
FROM
    My_Table MT
INNER JOIN dbo.Calendar CAL ON CAL.calendar_date = MT.ReturnDate

您需要填充 table,但这应该是一次性的工作(提前 50 年填充它,它仍然很小 table),您可以使用类似于我生成值的第一个语句的代码 - 不要手动输入每个日期;)之后,如果业务逻辑发生变化,你只需要维护 table (这比更改所有查询更容易处理日期)或者如果您有需要新列的新要求。