Access SQL似乎将日期视为dd / mm / yyyy?

时间:2017-07-04 16:07:51

标签: sql ms-access

我在MS Access中有一个表,其中包含员工详细信息(tblStaff):

| Employee Number |  Employee Name |  Dept     |
------------------------------------------------
|     205147      |   Joe Bloggs   |  IT       |
|     205442      |   John Doe     |  Accounts |

我每周用新数据刷新此表,如果有任何记录发生了变化(例如更改了dept),那么它们将被存档在另一个表(tblArchiveStaff)中,以及该记录有效的日期。

| Employee Number |  Employee Name |  Dept     | DateFrom | DateTo   |
----------------------------------------------------------------------
|     205147      |   Joe Bloggs   |  HR       | 03/01/16 | 01/06/17 |

我正在尝试编写一个查询,根据哪些表在给定日期有效,从这些表中选择记录

我们可以假设tblStaff中的记录在tblArchiveStaff中该雇员的最后一个条目的dateTo + 1有效,或者如果没有归档记录则从1月3日起有效。

到目前为止,我已经提出了下面的查询,我已经硬编码了#07/01/2017的日期条件#:

SELECT [Employee Number], [Dept], DateFrom, DateTo
FROM 

     (
      SELECT ts.[Employee Number], ts.[Dept], nz(ta2.DateTo,#01/02/16#)+1 AS DateFrom, date() AS DateTo
      FROM tblStaff ts LEFT JOIN tblArchiveStaff ta2 ON ts.[Employee Number] = ta2.[Employee Number]

      UNION ALL

      SELECT ta.[Employee Number], ta.[Dept], ta.DateFrom, ta.DateTo
      FROM tblArchiveStaff ta

     ) AS tblUnion

WHERE #07/01/2017# BETWEEN DateFrom AND DateTo;

据我所知,上述查询应该返回2017年7月1日有效的记录,这些记录既是tblStaff中的记录,又是在tblArchiveStaff中返回记录。它几乎就像它将日期条件视为1月7日,这意味着它的格式为dd / mm / yyyy,我认为这是不可能的。

有人可以解释一下吗?

2 个答案:

答案 0 :(得分:3)

那是因为你不遵守规则。始终将日期作为日期值处理,而不是字符串,而不是数字,没有例外。

因此,当您使用Nz甚至添加1时,联合查询无法找出数据类型,因此它会回退以将结果作为文本返回。然后,DateFrom变为文本,而DateTo是日期,这会过滤一个疯狂的猜测。

*编辑 - 我还修改了联合查询的第一部分,以确保当前记录来自最新的存档记录)

正确如此:

SELECT 
    tblUnion.[Employee Number], 
    tblUnion.[Dept], 
    tblUnion.DateFrom, 
    tblUnion.DateTo
FROM 
    (SELECT 
        ts.[Employee Number], 
        ts.[Dept], 
        DateAdd("d", 1, Nz(ta2.MaxDateTo, #01/02/16#)) AS DateFrom, 
        Date() AS DateTo
    FROM 
        tblStaff ts 
    LEFT JOIN 
       (SELECT 
        [Employee Number], 
        max(DateTo) AS MaxDateTo
    FROM 
        tblArchiveStaff
    GROUP BY 
       [Employee Number]) ta2 
        ON ts.[Employee Number] = ta2.[Employee Number]

    UNION ALL

    SELECT 
        ta.[Employee Number], 
        ta.[Dept], 
        ta.DateFrom, 
        ta.DateTo
    FROM 
        tblArchiveStaff ta) AS tblUnion
WHERE
    #7/1/2017# Between [DateFrom] And [DateTo];

您将获得所需的输出:

Employee Number Dept      DateFrom  DateTo
205147          IT        2017-01-07    2017-07-05
205442          Accounts  2016-01-03    2017-07-05

答案 1 :(得分:0)

标准日期翻转错误。尽量在代码中使用中性日期格式,例如

d MMM yyyy

1 Jul 2017(可行,但因语言差异而不推荐)

yyyy-MM-dd

2017-07-01(推荐,随处可用)