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.

Kursy walutowe
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 tej tabeli określono zestaw interwałów, które nie zachodzą na siebie. Data początkowa ma nazwę „Change Date”, a data końcowa 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.

W tym przykładowym skrypcie tabela In_Rates została utworzona za pomocą instrukcji load inline. Upewnij się, że daty w kolumnie Change Date są w takim samym formacie co data lokalna.

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 ];

Wykonaj następujące czynności:

  1. Określ, z którego zakresu czasu chcesz korzystać. Początek zakresu musi przypadać przed pierwszą datą w danych, a koniec po ostatniej.

    Let vBeginTime = Num('1/1/2013');
    Let vEndTime = Num('1/3/2013');
    Let vEpsilon = Pow(2,-27);
  1. 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 Currency, a następnie malejąco według „From Date”, aby najnowsze dane znalazły się na górze.

    Tmp_Rates:
    LOAD Currency, Rate,
    Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate
    Resident In_Rates;
  2. 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.

    Rates:
    LOAD Currency, Rate, FromDate,
    Date(If( Currency=Peek(Currency),
    Peek(FromDate) - $(#vEpsilon),
    $(#vEndTime)
    )) as ToDate
    Resident Tmp_Rates
    Order By Currency, FromDate Desc;
  3. Upuść tabelę wejściową i tabelę tymczasową.

    Drop Table Tmp_Rates;

Poniższy skrypt spowoduje aktualizację tabeli źródłowej w następujący sposób:

Zaktualizowana tabela źródłowa
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

Po uruchomieniu tego skryptu otrzymasz tabelę zawierającą prawidłowy wykaz interwałów. Skorzystaj z sekcji Podgląd w przeglądarce modelu danych, aby wyświetlić tabelę wynikową.

Podgląd danych
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

Tabelę tę można następnie porównać z istniejącą tabelą danych przy użyciu metodIntervalmatch.

Example:  

Cały skrypt aplikacji Qlik Sense 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;