【问题标题】:Converting MS Access query to T-SQL - datepart function将 MS Access 查询转换为 T-SQL - datepart 函数
【发布时间】:2015-08-11 11:26:20
【问题描述】:

我正在将一些 MS Access 查询转换为 T-SQL(用于 SQL 报告服务),但遇到了问题。

原来在 MS Access 查询中,有一个名为 DATEPART 的函数,它有两个可选参数(相应的 T-SQL DATEPART 函数没有的参数):firstdayofweek 和 firstweekofyear。而且我不知道如何在 T-SQL 中创建等效查询。

以下是原始的 MS Access 查询(精简为相关数据):

SELECT datepart("ww",OrderDate, 7, 2) AS WeekNumber FROM Orders;

注意:在这种情况下,7 表示以星期六为一周的第一天计算,2 表示以 4(或更多)天计算一年中的第一周。

如何在 T-SQL 中执行此操作?

【问题讨论】:

  • 是的,这就是我开始的地方。不幸的是,该函数不采用这两个可选参数(firstdayofweek 和 firstweekofyear),结果是不同的。为了给你一个想法,我整理了一个快速示例(一个在 SQL 中的 access 中)以查看结果,如果我输入日期 2014 年 4 月 1 日,访问给我第 13 周,SQL 给我第 14 周。但是如果我插入日期 4/1/2013,两者都给我 14,所以它不像从 SQL 结果中减去一个那么简单。
  • 这让我走到了一半——这确实涵盖了需要考虑周六和本周开始的部分。不幸的是,它无法将“第一”周视为有 4 天或更多天的那一周。

标签: sql tsql ms-access reporting-services datepart


【解决方案1】:

你提到的论点是:

第一天

被省略,Access 假定星期日是一周的第一天。该参数可以是下列值之一:

Constant    Value       Explanation
------------------------------------------------
vbUseSystem     0       Use the NLS API setting
vbSunday        1       Sunday (default)
vbMonday        2       Monday
vbTuesday       3       Tuesday
vbWednesday     4       Wednesday
vbThursday      5       Thursday
vbFriday        6       Friday
vbSaturday      7       Saturday

SQL Server SET DATEFIRST 中的等价物,注意它从星期一开始,而不是星期日,所以下面会返回 2(因为今天是星期二);

SET DATEFIRST 1;
SELECT [WEEKDAY] = DATEPART(WEEKDAY, CAST('2015-08-11' AS DATE));

下一个参数是:

第一周

可选。它是一个常数,用于指定一年中的第一周。如果省略此参数,Access 会假定包含 Jan 1st 的那一周是一年中的第一周。该参数可以是下列值之一:

Constant            Value   Explanation
---------------------------------------------------------------------------
vbUseSystem         0       Use the NSL API setting
vbFirstJan1         1       Use the first week that includes Jan 1st (default)
vbFirstFourDays     2       Use the first week in the year that has at least 4 days
vbFirstFullWeek     3       Use the first full week of the year

标准的DATEPART(WEEK, @Date) 相当于vbFirstJan1,这将在1 月1 日重置周数,然后在每次通过DATEFIRST 时增加1。

vbFirstFourDays最接近的是使用DATEPART(ISO_WEEK, @Date),ISO标准将一年中的第一周定义为包含4天的第一周,这并不完全等效,因为这不受DATEFIRST的影响,ISO 标准将周定义为星期一到星期日,因此ISO_WEEK 也可以,无论DATEFIRST 或区域设置如何。

根本没有与vbFirstFullWeek 等价的东西。

我发现通常是业务逻辑规定了与这些标准定义的周数或天数的任何偏差,因此这几乎总是最好的处理方法是为自己构建一个calendar table,然后您可以添加新列到它,并运行一次更新。例如,我必须报告从周四到周三的每周支付佣金,其中一年的第一周被定义为第一个完整的一周(所以在访问中这将是DATEPART("ww", [Date], 4, 5)),在MS SQL 我在日历表PaperSalesCommissionWeekNumber 中添加了一个新列,然后我可以加入我的日历表以获取周数:

SELECT  c.PaperSalesCommissionWeekNumber
FROM    dbo.Deal AS d
        INNER JOIN dbo.Calender AS c
            ON d.DealDate = c.DateKey;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多