Een datuminterval maken op basis van een enkele datum

Soms worden tijdsintervallen niet expliciet opgeslagen met een begin en een einde. In plaats daarvan worden zij geïmpliceerd door slechts één veld: het wijzigingstijdstempel.

Dit kan zijn zoals in de onderstaande tabel, waarin u wisselkoersen voor meerdere valuta's hebt. Elke verandering in wisselkoers bevindt zich op een eigen rij, elk met een nieuwe wisselkoers. Ook bevat de tabel rijen met lege datums die overeenkomen met de oorspronkelijke wisselkoers, voordat de eerste wijziging werd aangebracht.

Valutakoersen
Valuta Wijzigingsdatum 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

Deze tabel definieert een reeks van niet-overlappende intervallen, waarbij de begingegevens “Change Date” worden genoemd en de einddatum wordt gedefinieerd door het begin van de volgende interval. Maar aangezien de einddatum niet expliciet in een eigen kolom is opgeslagen, moeten we een dergelijke kolom maken, zodat de nieuwe tabel een lijst met intervallen wordt.

In dit scriptvoorbeeld wordt de tabel In_Rates gemaakt door een inline load-opdracht. Zorg ervoor dat de datums in de kolom Change Date dezelfde opmaak hebben als de lokale datumopmaak.

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

Doe het volgende:

  1. Bepaal met welk tijdbereik u wilt werken. Het begin van het bereik moet vóór de eerste datum in de gegevens liggen en het einde van het bereik moet na de laatste datum liggen.

    Let vBeginTime = Num('1/1/2013');
    Let vEndTime = Num('1/3/2013');
    Let vEpsilon = Pow(2,-27);
  1. Laad de brongegevens, maar wijzig lege datums aan het begin van het bereik dat is gedefinieerd bij het vorige opsommingsteken. De wijzigingsdatum moet worden geladen als From Date.

    Sorteer de tabel eerst op Currency en vervolgens in aflopende volgorde op de “From Date” zodat de meest recente datums bovenaan staan.

    Tmp_Rates:
    LOAD Currency, Rate,
    Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate
    Resident In_Rates;
  2. Voer een tweede run uit op de gegevens waarbij u de To Date berekent. Als de huidige record een andere valuta heeft dan de vorige records, is het de eerste record van een nieuwe valuta (maar het laatste interval hiervan), dus kunt u het beste het einde van het bereik gebruiken dat is gedefinieerd in stap 1. Als het dezelfde valuta is, neemt u de “From Date” van de vorige record, trekt u een kleine hoeveelheid tijd af en gebruikt u deze waarde als “To Date” in de huidige record.

    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. Verwijder de invoertabel en de tijdelijke tabel.

    Drop Table Tmp_Rates;

In het hierop aangegeven script wordt de brontabel als volgt bijgewerkt:

Bijgewerkte brontabel
Valuta 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

Als het script wordt uitgevoerd, beschikt u over een tabel waarin de intervallen op correcte wijze worden weergegeven. Gebruik de sectie Voorbeeld van de gegevensmodelviewer om de resulterende tabel te bekijken.

Voorbeeld van gegevens
Valuta 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

Deze tabel kan vervolgens worden gebruikt in een vergelijking met een bestaande datum via de Intervalmatch-methoden.

Example:  

Het volledige Qlik Sense-script ziet er als volgt uit:

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;