Find Days Home SQL Query - PullRequest
       4

Find Days Home SQL Query

1 голос
/ 12 февраля 2012

У меня есть список поездок, которые совершали люди в моей организации.Цель состоит в том, чтобы рассчитать время, в течение которого человек находился дома между поездками, рассматривая прошлое и будущее в запланированных поездках.Поездки не были введены в хронологическом порядке.Я хочу выполнить запрос к таблице, чтобы заполнить 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 голосов
/ 12 февраля 2012

В моей версии таблицы «Поездки» я изменил имя поля «Имя» на «Персона», потому что Имя - это зарезервированное слово.Я использовал DMax (), чтобы найти самую последнюю дату возвращения человека перед каждым отъездом.Тогда DaysHome может быть основан на выражении DateDiff () между prev_return и Departed.

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

Обратите внимание, что моя версия имеет значение Null для DaysHomeза то, что вы назвали «базовым путешествием».Но вы сказали, что хотите вместо этого ноль.IMO Null здесь более значим, потому что вы не можете сказать, сколько дней этот человек находился дома до своего первого отъезда.Но если вам действительно нужен ноль, используйте функцию Nz () с этим выражением DateDiff ().

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

Также вы сказали: «Я знаю, мне нужен запрос на обновление».Не храните DaysHome в таблице поездок;не храните это нигде.Просто вычислите это при необходимости.Если вы храните его где-либо, ваши значения могут быть не синхронизированы при изменении данных отключений.

Редактировать : вы полны решимости сохранить производные значения в вашей таблице поездок.Поскольку вы сказали нам «Я использую Access 2007 для этого запроса», это означает, что вы можете использовать пользовательскую функцию VBA в своем запросе UPDATE.Используя приведенную ниже функцию GetDaysHome (), ваш запрос UPDATE может быть таким простым:

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

Или, если вы действительно хотите использовать ноль вместо Null в качестве DaysHome для "базовых отключений", используйте Nz () функция:

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

Обратите внимание, что я переименовал поле Имя в Персона, потому что Имя - это зарезервированное слово.

Хотя вы можете сделать ОБНОВЛЕНИЕ, используя только простой 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...