Tworzenie interwałów na podstawie daty
Czasami interwały czasu nie są zapisywane jawnie z początkiem i końcem. Zamiast tego wynikają z tylko jednego pola — znacznika czasu zmiany.
Przykładem może być poniższa tabela zawierająca różne kursy walutowe. Każda zmiana kursu walutowego zachodzi we własnym wierszu — z nowym kursem wymiany. Ponadto tabela ta zawiera wiersze z pustymi datami odpowiadającymi początkowemu kursowi wymiany, przed dokonaniem pierwszej zmiany.
Waluta | Data wymiany | Rate |
---|---|---|
EUR | - | 8.59 |
EUR | 28/01/2013 | 8.69 |
EUR | 15/02/2013 | 8.45 |
USD | - | 6.50 |
USD | 10/01/2013 | 6.56 |
USD | 03/02/2013 | 6.30 |
W powyższej tabeli określono zestaw interwałów, które nie zachodzą na siebie. Data początkowa ma nazwę Change Date, a data zakończenia jest zdefiniowana przez początek następnego interwału. Data końcowa nie jest jawnie zapisywana we własnej kolumnie, musimy zatem utworzyć taką kolumnę, aby nowa tabela stała się listą interwałów.
Wykonaj następujące czynności:
- Utwórz nową aplikację i nadaj jej nazwę.
- Dodaj nową sekcję skryptu w edytorze ładowania danych.
- Dodaj następującą tabelę wbudowaną. Upewnij się, że daty w kolumnie Change Date są w takim samym formacie co data lokalna.
-
Określ, z którego zakresu czasu chcesz korzystać. Początek zakresu musi przypadać przed pierwszą datą w danych, a koniec po ostatniej.
Dodaj następującą treść na początku swojego skryptu:
Let vBeginTime = Num('1/1/2013'); Let vEndTime = Num('1/3/2013'); Let vEpsilon = Pow(2,-27);
-
Załaduj dane źródłowe, ale zmień puste daty na początek zakresu określonego w poprzednim punkcie. Data zmiany powinna być załadowana jako "From Date".
Posortuj tabelę najpierw według wartości Currency, a następnie malejąco według wartości "From Date", aby najnowsze dane znalazły się na górze.
Dodaj następującą treść po tabeli In_Rates:
Tmp_Rates: LOAD Currency, Rate, Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate Resident In_Rates;
-
Uruchom drugie przejście przez dane, aby obliczyć "To Date". Jeśli bieżący rekord zawiera inną walutę niż poprzedni, jest to pierwszy rekord nowej waluty (ale jej ostatni interwał), należy zatem użyć końca zakresu zdefiniowanego w kroku 1. Jeśli jest to ta sama waluta, należy użyć wartości "From Date" z poprzedniego rekordu, odjąć małą ilość czasu i użyć jej jako wartości "To Date" w bieżącym rekordzie.
Dodaj następującą treść po tabeli Tmp_Rates:
Rates: LOAD Currency, Rate, FromDate, Date(If( Currency=Peek('Currency'), Peek('FromDate') - $(#vEpsilon), $(#vEndTime) )) as ToDate Resident Tmp_Rates Order By Currency, FromDate Desc; Drop Table Tmp_Rates;
In_Rates:
LOAD * Inline [
Currency,Change Date,Rate
EUR,,8.59
EUR,28/01/2013,8.69
EUR,15/02/2013,8.45
USD,,6.50
USD,10/01/2013,6.56
USD,03/02/2013,6.30
];
Skrypt powinien wyglądać następująco:
Let vBeginTime = Num('1/1/2013');
Let vEndTime = Num('1/3/2013');
Let vEpsilon = Pow(2,-27);
In_Rates:
LOAD * Inline [
Currency,Change Date,Rate
EUR,,8.59
EUR,28/01/2013,8.69
EUR,15/02/2013,8.45
USD,,6.50
USD,10/01/2013,6.56
USD,03/02/2013,6.30
];
Tmp_Rates:
LOAD Currency, Rate,
Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate
Resident In_Rates;
Rates:
LOAD Currency, Rate, FromDate,
Date(If( Currency=Peek('Currency'),
Peek('FromDate') - $(#vEpsilon),
$(#vEndTime)
)) as ToDate
Resident Tmp_Rates
Order By Currency, FromDate Desc;
Drop Table Tmp_Rates;
Skrypt zaktualizuje tabelę źródłową w następujący sposób:
Waluta | Rate | FromDate | ToDate |
---|---|---|---|
EUR | 8.45 | 15/02/2013 | vEndTime |
EUR | 8.69 | 28/01/2013 | 14/02/2013 23:59:59 |
EUR | 8.59 | vBeginTime | 28/01/2013 23:59:99 |
USD | 6.30 | 03/02/2013 | vEndTime |
USD | 6.56 | 10/01/2013 | 2/02/2013 23:59:59 |
USD | 6.50 | vBeginTime | 9/01/2013 23:59:59 |
W aplikacji tabela będzie wyglądać następująco:
Waluta | Rate | FromDate | ToDate |
---|---|---|---|
EUR | 8.45 | 15/02/2013 | 01/03/2013 |
EUR | 8.69 | 28/01/2013 | 14/02/2013 |
EUR | 8.59 | 01/01/2013 | 28/01/2013 |
USD | 6.30 | 03/02/2013 | 01/03/2013 |
USD | 6.56 | 10/01/2013 | 2/02/2013 |
USD | 6.50 | 01/01/2013 | 9/01/2013 |
Tabeli tej można następnie użyć w porównaniu z istniejącą datą przy użyciu metody Intervalmatch.