2014-06-26 64 views
0

我有一个问题,我根本无法弄清楚。我有一个不同旅行日期的员工名单,我想以级联列表格式显示所有人。问题是我只想看到员工一次,只有最接近今天的日期。访问SQL查询:比较选择语句中的日期

例如,我可以在那里多次使用'Smith',日期在今天之前和之后,因为我们也保留了历史记录。这意味着我不能只做分钟,因为它会尝试在今天之前显示一个日期,并且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())); 

我按名称做了一个组,因为我只想看到每个人一次。如果我不通过连接将表添加到自身,它会给出自我引用错误。这是我第一次发布,所以我希望这是有道理的!所有帮助将不胜感激!

+3

您使用的数据库是?您正在将SQL Server/Sybase约定与MySQL约定混合使用。另外,你为什么要做自我加入。这个不成立。 –

+0

对不起,我正在使用MS Access – user3779582

回答

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] 
    ) 

这样可以保证你获得1行每FSR名称,即使有与相同的“最新”的日期是FSR多行。否则,您可以省略处理pk_value的辅助查询,但是对于具有多个具有相同“最新”日期的记录的FSR,您可能会获取多行的风险。

注意:当您开始查询这个复杂的,运行于全功能数据库(SQL Server,Oracle,除Access之外的其他任何软件)时,您可以使用更复杂的功能。对于这个例子,“窗口函数”会给你答案没有太多的争论。不知道你现在是否被Access困住了,但无论如何都要考虑到这一点。

+0

我重新格式化为以下内容: 'SELECT'Last Name'AS [Last Name], Min('Date In')AS [Date In], Max(Site )AS Site, Max(Position)AS Position, Max(Comments)AS Comments FROM Deployments GROUP BY'Last Name' WHERE'Date In'> Now(); ' '但它给了我这个错误 - “语法错误(缺少操作符)在查询表达式''姓''WHERE'日期在'>现在()'我也道歉,但我不知道如何格式化评论让它看起来更好 – user3779582

+0

我原来的GROUP BY后面会出现WHERE,这会导致语法错误,现在上面的答案已经解决了,对不起! – SlimsGhost

+0

嗯,它越来越接近了!现在告诉我我有一个循环引用我发现在你的回复中你仍然有部署AS A,但是没有部署AS B,应该再次在那里吗?编辑:我把它放进去了,它工作了!唯一奇怪的是Access当我运行查询时要求输入名称和日期,如果我输入了什么,它会输出正确的信息。我想知道如何让它不要求输入? – user3779582

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)) 

取而代之的是搞笑分钟和马克塞斯您正在使用,试图获得与最接近今天datein行,请尝试使用DATEDIFF。使用此功能,您可以指定要比较哪种日期或时间值(日,月,年,分),然后查找两个不同日期时间之间的差异。在这种情况下,我使用getdate()来查找当前的日期和时间。然后,我们要为dateiff值最小的datein,即最接近今天的datein。 Datediff将返回正值或负值,所以我使用abs来获得结果的绝对值。我这样做是因为如果日期在今天之前或今天之后,无关紧要。

然后我们正在查看部署表。子查询表示我们应该查看所有不是当前值的值。然后,查找所有具有比当前记录更小的datediff的行。此外,找到所有与当前记录相同的记录以及较小的记录。如果没有符合此标准的任何内容,我们将只包含当前记录。这是一个有点奇怪的想法,但这种类型的查询应该可以帮助你更容易地找到你正在寻找的东西。唯一的问题是,您需要在子查询的where子句中添加条件以确定要比较的条目。就目前而言,该查询将查看部署表中的所有条目,并将具有最接近今天的日期的一行撤回。既然你想为每个人一行,这将需要更多的规格。

+0

嗯,我给了这个镜头,但它给出了一个错误,说明它太复杂,评估或输入不正确。我也不确定它是否会将网站/位置/评论适当地链接起来。 – user3779582

+0

@ user3779582刚看了一遍,我肯定错过了几个parens。正如我的答案所解释的,您需要在子查询的where子句中添加一些内容。我不确定'id'是什么。如果你有几个史密斯的记录,每个记录是否有自己的ID或他们都是一样的? – Jenn

+0

不幸的是,我正在处理的数据库以姓氏的形式使用Natural Keys。所以是每个记录的每个ID是不同的。我遇到的问题是,即使来自其他人的答案,我也无法让这两件事情相匹配。即使我使用简化方法,我也无法弄清楚它的逻辑。我会认为有A.ID = B.ID就够了,但我猜不是吗? – user3779582