Ms access 查找天主页SQL查询

Ms access 查找天主页SQL查询,ms-access,join,Ms Access,Join,我有一份我所在组织的人员参加的旅行的清单。目标是计算个人在旅行之间回家的时间,回顾过去和未来。行程没有按时间顺序输入。我想在表上运行一个查询,以填充每次旅行的DaysHome Table: Trips Name DaysHome Departed Returned Evan 1/1/2011 2/1/2011 Joe 2/1/2011 5/1/2011 Evan 3/10/2011

我有一份我所在组织的人员参加的旅行的清单。目标是计算个人在旅行之间回家的时间,回顾过去和未来。行程没有按时间顺序输入。我想在表上运行一个查询,以填充每次旅行的DaysHome

Table: Trips
Name    DaysHome Departed      Returned
Evan             1/1/2011      2/1/2011
Joe              2/1/2011      5/1/2011
Evan             3/10/2011     4/10/2011
Evan             1/1/2010      6/1/2010
Joe              6/1/2011      7/1/2011
理想情况下,在查询之后,该表将如下所示,显然,为该人员输入的第一次行程时间将为0,因为它是基线行程

Table: Trips
Name    DaysHome Departed      Returned
Evan    180      1/1/2011      2/1/2011
Joe     0        2/1/2011      5/1/2011
Evan    30       3/10/2011     4/10/2011
Evan    0        1/1/2010      6/1/2010
Joe     30       6/1/2011      7/1/2011
非常感谢您的帮助。我知道我需要一个更新查询,我只是不知道我是否需要一个连接,或者我是否可以只做一个嵌套的MAX搜索


我正在使用Access 2007进行此查询。

在我的Trips表版本中,我将字段名“name”更改为“Person”,因为name是一个保留字。我使用DMax()查找此人每次出发前的最近返回日期。然后DaysHome可以基于prev_return和deceed之间的DateDiff()表达式

SELECT
    sub.Person,
    sub.Departed,
    sub.Returned,
    sub.prev_return,
    DateDiff('d',sub.prev_return,sub.Departed) AS DaysHome
FROM
    (
        SELECT
            t.Person,
            t.Departed,
            t.Returned,
            DMax("Returned", "Trips",
                "Person = '" & Person
                & "' AND Returned <= "
                & Format(Departed, "\#yyyy-mm-dd\#"))
                AS prev_return
        FROM Trips AS t
    ) AS sub
ORDER BY sub.Person, sub.Departed;
请注意,对于您所谓的“基线旅行”,我的版本的DaysHome为Null。但你说你想要零。IMO Null在这里更有意义,因为你不能说那个人在第一次离开之前回家了多少天。但是,如果您确实想要零,请将Nz()函数与DateDiff()表达式一起使用

Nz(DateDiff('d',sub.prev_return,sub.Departed), 0) AS DaysHome
你还说“我知道我需要一个更新查询”。不要将DaysHome存储在Trips表中;不要把它存放在任何地方。只需在需要时进行计算。如果将其存储在任何位置,当Trips数据更改时,您的值可能会不同步

编辑:您决定在Trips表中存储派生值。由于您告诉我们“我正在使用Access 2007进行此查询”,这意味着您可以在更新查询中使用VBA用户定义函数。使用下面的GetDaysHome()函数,您的更新查询可以像下面这样简单:

UPDATE Trips
SET Trips.DaysHome = GetDaysHome([Person],[Departed]);
或者,如果您确实希望“基线行程”的DaysHome为零而不是Null,请使用Nz()函数:

UPDATE Trips
SET Trips.DaysHome = Nz(GetDaysHome([Person],[Departed]), 0);
注意,我将Name字段重新命名为Person,因为Name是一个保留字

虽然您可以只使用普通SQL(不使用UDF)进行更新,但这种方法对我来说编写、测试和描述要快得多

Public Function GetDaysHome(ByVal pName As String, _
        ByVal pDeparture As Date) As Variant
    Dim strCriteria As String
    Dim varOut As Variant
    Dim varPrevReturned As Variant

    strCriteria = "Person = '" & pName & _
        "' AND Returned <= " & _
        Format(pDeparture, "\#yyyy-mm-dd\#")
    varPrevReturned = DMax("Returned", "Trips", strCriteria)
    If Not IsNull(varPrevReturned) Then
        varOut = DateDiff("d", varPrevReturned, pDeparture)
    End If
    GetDaysHome = varOut
End Function
公共函数GetDaysHome(ByVal pName作为字符串_
ByVal pDeparture As Date)作为变量
作为字符串的Dim strCriteria
Dim varOut作为变体
Dim varprev作为变量返回
strCriteria=“Person=”&pName&_

“'并返回有没有办法将其转换为更新,以便将days home数据写回原始表?我知道这并不理想(或良好做法)但是我的办公室使用表本身作为唯一的数据源。这意味着一个排除信息的查询将没有那么有用,我现在正在尝试您的解决方案,我们不需要一个max函数来确保它选择最新的返回吗?我很难将此转换为更新查询。感谢您迄今为止的出色帮助UGH您可以轻松地将其转换为make table查询。虽然这会复制Trips中的数据,但至少可以保证DaysHome与Trips数据快照一致。我想将DaysHome从上面的答案更新到原始表中,有什么建议吗?
Public Function GetDaysHome(ByVal pName As String, _
        ByVal pDeparture As Date) As Variant
    Dim strCriteria As String
    Dim varOut As Variant
    Dim varPrevReturned As Variant

    strCriteria = "Person = '" & pName & _
        "' AND Returned <= " & _
        Format(pDeparture, "\#yyyy-mm-dd\#")
    varPrevReturned = DMax("Returned", "Trips", strCriteria)
    If Not IsNull(varPrevReturned) Then
        varOut = DateDiff("d", varPrevReturned, pDeparture)
    End If
    GetDaysHome = varOut
End Function