查找Days Home SQL查询

时间:2012-02-12 17:37:34

标签: 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     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进行此查询。

1 个答案:

答案 0 :(得分:0)

在我的Trips表版本中,我将字段名称“Name”更改为“Person”,因为Name是一个保留字。我使用DMax()来查找每个人在每次出发前的最近返回日期。然后,DaysHome可以基于prev_return和Departed之间的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;

这是该查询的结果集。

Person Departed  Returned   prev_return DaysHome
Evan    1/1/2010  6/1/2010
Evan    1/1/2011  2/1/2011     6/1/2010      214
Evan   3/10/2011 4/10/2011     2/1/2011       37
Joe     2/1/2011  5/1/2011
Joe     6/1/2011  7/1/2011     5/1/2011       31

请注意,对于您所谓的“基线旅行”,我的版本对于DaysHome具有Null。但你说你想要零而不是。 IMO Null在这里更有意义,因为你不能说这个人在他第一次离开之前有多少天回家。但是如果你真的想要零,那么使用带有DateDiff()表达式的Nz()函数。

Nz(DateDiff('d',sub.prev_return,sub.Departed), 0) AS DaysHome

你也说“我知道我需要一个更新查询”。不要将DaysHome存储在Trips表中;不要把它存放在任何地方。只需在需要时进行计算。如果将其存储在任何位置,则在更改Trips数据时,您的值可能会不同步。

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

UPDATE Trips
SET Trips.DaysHome = GetDaysHome([Person],[Departed]);

或者,如果你真的希望零而不是Null作为“基线旅行”的DaysHome,请使用Nz()函数:

UPDATE Trips
SET Trips.DaysHome = Nz(GetDaysHome([Person],[Departed]), 0);

注意我将Name字段重命名为Person,因为Name是保留字。

虽然你可以只使用普通的SQL(没有UDF)来进行UPDATE,但这种方法对我来说编写,测试和描述的速度要快得多。

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