访问SQL查询:在Select语句中比较日期

时间:2014-06-26 13:46:54

标签: sql date ms-access

我有一个问题,我似乎无法弄明白。我有一份具有不同旅行日期的员工列表,我希望以级联列表格式显示所有这些。问题是我只想看到员工一次,而且只看到最接近今天的日期。

例如,我可以在今天之前和之后多次出现'史密斯',因为我们也保留了历史记录。这意味着我不能只做min,因为它会尝试在今天之前显示一个日期,并且max太远了。

ALMOST下面的代码示例有效。问题出在select语句中。我想显示今天之后的最短日期,但它给出了0和-1的日期应该是。可能只有另一种方法可以一起完成所有这些,但这是唯一允许其他信息(如站点,位置和注释)与其一起正确显示的配置。

SELECT A.`Last Name` AS [Last Name], Min(A.`Date In`) > Now() AS [Date In], Max(B.Site) AS Site, Max(B.Position), Max(B.Comments) AS Comments
FROM Deployments AS A 
INNER JOIN Deployments AS B ON A.ID = B.ID
GROUP BY A.`FSR Name`
HAVING (((Max(A.`Actual TEP IN`))>Now()));

我按姓名做了一个小组,因为我只希望看到每个人一次。如果我没有使用连接将表添加到自身,则会出现自引用错误。这是我第一次发帖,所以我希望这是有道理的!非常感谢所有帮助!

2 个答案:

答案 0 :(得分:0)

不确定你在使用什么数据库,但一般来说,你需要返回MIN(日期)而不是比较结果“Min(Date)> Now()” - 我猜这是哪里你看到的是0和-1,因为这是比较的结果,当你想要最小的日期值时。

此外,如果您只是想要将来拥有旅行日期的人,只需使用WHERE子句限制查询,执行GROUP BY,即可摆脱自联接。另请注意,下面的示例将OP中的一些差异与您根据“姓氏”选择的位置进行对齐,但在“FSR名称”上进行分组 - 这些内容必须一致,无论您关注哪个字段。

示例:

SELECT A.[FSR Name] AS [FSR Name], 
    Min(A.[Date In]) AS [Date In], 
    Max(A.Site) AS Site, 
    Max(A.Position) AS Position,
    Max(A.Comments) AS Comments
FROM Deployments AS A 
WHERE A.[Date In] > Now()
GROUP BY A.[FSR Name];

编辑:如果您需要确保网站,位置,评论都来自同一行,您必须执行以下某个选项之类的操作:

如果您有主键:

select * from Deployments A3 where A3.pk_value = 
    (select max(A2.pk_value) from Deployments A2 
     where A2.[Date In] = 
        (select Max([Date In]) from Deployments A where A.[FSR Name] = A2.[FSR Name])
     and A2.[FSR Name] = A3.[FSR Name]
    )

这可以保证每个FSR名称获得1行,即使该FSR有多行具有相同的“最新”日期。

否则,您可以省略处理pk_value的辅助查询,但是您可能会为具有多个具有相同“最新”日期的记录的FSR获取多行。

注意:当你对这个复杂的查询进行查询时,在一个功能齐全的数据库(SQL Server,Oracle,除Access之外的任何东西)上运行可以让你使用更复杂的东西。对于这个例子,“窗口函数”会给你答案,而不需要那么多的争论。不确定你现在是否仍然使用Access,但无论如何都要考虑将来。

答案 1 :(得分:0)

尝试这样的事情

Select A.LastName, A.DateIn, A.Site, A.Position, A.Comments
From deployments a
Where  not exists (Select *
                From deployments b
                Where b.id <> a.id
                and     (abs(datediff(d, getdate(), a.datein))) > abs(datediff(d, getdate(), b.datein))
                or abs(datediff(d, getdate(), a.datein)) = abs(datediff(d, getdate(), b.datein) and a.id > b.id))

尝试使用datediff,而不是尝试使用最接近今天的datein的行来使用有趣的分钟和最大值。使用此功能,您可以指定要比较的日期或时间值的类型(日,月,年,分),然后查找两个不同日期时间之间的差异。在这种情况下,我使用getdate()来查找当前的日期和时间。然后,我们希望datein具有最小值的datediff,即最接近今天的datein。 Datediff将返回正值或负值,因此我使用abs来获得结果的绝对值。我这样做是因为日期是在今天之前还是在今天之后无关紧要。

然后我们查看部署表。子查询说我们应该查看所有不是当前值的值。然后,找到比当前记录更小的日期的所有行。此外,查找与当前记录具有相同日期和所有较小ID的所有记录。如果没有符合此标准的任何内容,我们将仅包括当前记录。考虑一下有点奇怪,但这种类型的查询应该可以帮助您更轻松地找到您正在寻找的内容。唯一的事情是您需要在子查询的where子句中添加条件以确定要比较的条目。就目前而言,此查询将查看部署表中的所有条目,并撤回具有最接近今天的日期的一行。由于每个人都需要一行,因此需要更多规范。