2012-02-12 73 views
1

我有一個組織中的人員已經採取的旅行列表。我們的目標是計算出一個人在兩次出行之間回家的時間,並在計劃的行程中查看過去和未來。這些旅行並沒有按時間順序輸入。我想在表格上運行查詢以填充每次旅行的DaysHome。查找天數首頁SQL查詢

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 

任何幫助,非常感謝。我知道我需要一個更新查詢,我只是不知道我是否需要一個Join,或者如果我可以做一個嵌套的MAX搜索。

我對此查詢使用Access 2007。

回答

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 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 
+0

有什麼辦法可以把它變成UPDATE,這樣天家的數據被寫回到原始表中嗎? – user1204214 2012-02-12 19:06:58

+0

我知道它不是理想的(或好的做法),但我的辦公室使用表格本身作爲唯一的數據來源。這意味着一個查詢信息不會有用,我現在正在嘗試您的解決方案,我們是否需要某個地方的最大功能來確保它能夠選擇最近的回報? – user1204214 2012-02-12 19:18:14

+0

我很失敗,把它變成更新查詢。感謝您迄今爲止的精彩幫助,儘管 – user1204214 2012-02-12 20:04:14