Vai al contenuto principale

Corrispondenza degli intervalli e caricamento iterativo

Il prefisso Intervalmatch in un'istruzione LOAD o SELECT  viene utilizzato per collegare valori numerici discreti a uno o più intervalli numerici. Si tratta di una funzione molto avanzata che può essere utilizzata, ad esempio, negli ambienti di produzione.

Utilizzo del prefisso IntervalMatch()

La corrispondenza dell'intervallo più semplice consiste nel disporre di numeri o date (eventi) in una tabella e di un elenco di intervalli in una seconda tabella. L'obiettivo è quello di collegare le due tabelle. In generale, si tratta di una relazione molti a molti, vale a dire che un intervallo può presentare diverse date che gli appartengono e una data può appartenere a diversi intervalli. Per eseguire questo collegamento, occorre creare una tabella ponte tra le due tabelle originali. Sono disponibili diversi modi per eseguire questa operazione.

Il modo più semplice per risolvere questo problema in Qlik Sense è quello di utilizzare il prefisso IntervalMatch() davanti a un'istruzione LOAD o SELECT. L'istruzione LOAD/SELECT deve contenere solo due campi, i campi From e To che definiscono gli intervalli. Il prefisso IntervalMatch() genererà quindi tutte le combinazioni tra gli intervalli caricati e un campo numerico caricato in precedenza, specificato come parametro per il prefisso.

Procedere come indicato di seguito:

  1. Creare una nuova app e assegnarle un nome.
  2. Aggiungere una nuova sezione dello script nell'editor caricamento dati.
  3. Richiamare le sezioni Events.
  4. Nel menu a destra, in DataFiles, fare clic su Seleziona dati.

  5. Caricare e selezionare Events.txt.
  6. Nella finestra Seleziona dati da, fare clic su Inserisci script.
  7. Caricare e selezionare Intervals.txt.
  8. Nella finestra Seleziona dati da, fare clic su Inserisci script.
  9. Nello script, denominare la prima tabella Eventi e la seconda Intervals.
  10. Alla fine dello script aggiungere IntervalMatch per creare una terza tabella che serva da ponte tra le due prime tabelle:
  11. BridgeTable: IntervalMatch (EventDate) LOAD distinct IntervalBegin, IntervalEnd Resident Intervals;
  12. Lo script avrà questo aspetto:
  13. Eventi: LOAD EventID, EventDate, EventAttribute FROM [lib://DataFiles/Events.txt] (txt, utf8, embedded labels, delimiter is '\t', msq);   Intervals: LOAD IntervalID, IntervalAttribute, IntervalBegin, IntervalEnd FROM [lib://DataFiles/Intervals.txt] (txt, utf8, embedded labels, delimiter is '\t', msq);   BridgeTable: IntervalMatch (EventDate) LOAD distinct IntervalBegin, IntervalEnd Resident Intervals;

  14. Fare clic su Carica dati.
  15. Aprire il sistema di visualizzazione modello dati. Il modello dati ha l'aspetto seguente:
  16. Modello dati: tabelle Events, BridgeTable, Intervals e $Syn1
    Data model: Events, BridgeTable, Intervals, and $Syn1 tables.

    Il modello dati contiene una chiave composita (i campi IntervalBegin e IntervalEnd) che, in Qlik Sense, diventerà una chiave sintetica:

    Le tabelle di base sono:

    • La tabella Events che contiene esattamente un record per evento.
    • La tabella Intervals che contiene esattamente un record per intervallo.
    • La tabella ponte che contiene esattamente un record per combinazione di evento e intervallo e che collega le due tabelle precedenti.

    Tenere presente che un evento può appartenere a diversi intervalli se gli intervalli si sovrappongono. Inoltre un intervallo può presentare diversi eventi che gli appartengono.

    Questo modello dati è ideale poiché è normalizzato e compatto. La tabella Events e la tabella Intervals sono entrambe inalterate e contengono il numero di record originale. Tutti i calcoli di Qlik Sense applicati a queste tabelle, ad esempio Count(EventID), funzioneranno e saranno valutati correttamente.

Nota informaticaPer ulteriori informazioni su IntervalMatch(), vedere questo post di blog in Qlik Community: Using IntervalMatch() (Utilizzo di IntervalMatch())

Utilizzo di un ciclo While e del caricamento iterativo IterNo()

È possibile ottenere quasi la stessa tabella ponte utilizzando il ciclo While e IterNo() che crea valori enumerabili tra il limite inferiore e superiore dell'intervallo.

È possibile creare un ciclo all'interno dell'istruzione LOAD mediante la clausola While. Ad esempio:

LOAD Date, IterNo() as Iteration From … While IterNo() <= 4;

Un'istruzione LOAD di questo tipo eseguirà il ciclo su ogni record di input ed eseguirà il caricamento ripetutamente purché l'espressione nella clausola While sia vera. La funzione IterNo() restituisce "1" nella prima iterazione, "2" nella seconda e così via.

Per gli intervalli si dispone di una chiave primaria, IntervalID, quindi l'unica differenza nello script sarà come viene creata la tabella ponte:

Procedere come indicato di seguito:

  1. Sostituire le istruzioni Bridgetable esistenti con lo script seguente:
  2. BridgeTable: LOAD distinct * Where Exists(EventDate); LOAD IntervalBegin + IterNo() - 1 as EventDate, IntervalID Resident Intervals While IntervalBegin + IterNo() - 1 <= IntervalEnd;

  3. Fare clic su Carica dati.
  4. Aprire il sistema di visualizzazione modello dati. Il modello dati ha l'aspetto seguente:
  5. Modello dati: Tabelle Events, BridgeTable e Intervals
    Data model: Events, BridgeTable, and Intervals tables.

    In generale, la soluzione con le tre tabelle è la migliore poiché consente di instaurare una relazione molti a molti tra gli intervalli e gli eventi. Tuttavia, una situazione molto comune è quella di un evento che può appartenere solo a un unico intervallo. In questo caso, la tabella ponte non è realmente necessaria: IntervalID può essere memorizzato direttamente nella tabella degli eventi. Sono disponibili diversi modi per eseguire questa operazione, tuttavia quello più utile è unire Bridgetable alla tabella Events.

  6. Aggiungere lo script seguente alla fine dello script:
  7. Join (Events) LOAD EventDate, IntervalID Resident BridgeTable; Drop Table BridgeTable;

  8. Fare clic su Carica dati.
  9. Aprire il sistema di visualizzazione modello dati. Il modello dati ha l'aspetto seguente:
  10. Modello dati: Tabelle Events e Intervals
    Data model: Events and Intervals tables.

Intervalli aperti e chiusi

Lo stato aperto o chiuso di un intervallo viene determinato dai punti finali, indipendentemente dal fatto che siano inclusi o meno nell'intervallo.

  • Se vengono inclusi i punti finali, si parla di intervallo chiuso:
  • [a,b] = {x ∈ ℝ ∣ a ≤ x ≤ b}

  • Se non vengono inclusi i punti finali, si parla di intervallo aperto:
  • ]a,b[ = {x ∈ ℝ ∣ a < x < b}

  • Se viene incluso un punto finale, si parla di intervallo semi aperto:
  • [a,b[ = {x ∈ ℝ ∣ a ≤ x < b}

Nel caso in cui gli intervalli si sovrappongano e un numero possa appartenere a più di un intervallo, in generale, occorre utilizzare intervalli chiusi.

Tuttavia, in alcuni casi, non si desidera la sovrapposizione degli intervalli, ma che un numero appartenga a un unico intervallo. Di conseguenza, il problema sorge nel caso in cui un punto corrisponde alla fine di un intervallo e, contemporaneamente, all'inizio di quello successivo. Un numero con questo valore verrà attribuito a entrambi gli intervalli. Gli intervalli semi aperti rappresentano quindi la soluzione ideale.

Una soluzione pratica al problema è quella di sottrarre una cifra minima dal valore finale di tutti gli intervalli, creando quindi intervalli chiusi ma che non si sovrappongono. Se i numeri disponibili sono date, il modo più semplice per eseguire questa operazione è utilizzare la funzione DayEnd(), che restituisce l'ultimo millisecondo del giorno:

Intervalli: LOAD…, DayEnd(IntervalEnd – 1) as IntervalEnd From Intervals;

È anche possibile sottrarre una piccola cifra manualmente. In questo caso, assicurarsi che la cifra sottratta non sia eccessivamente ridotta dato che l'operazione verrà arrotondata in base a 52 cifre binarie significative (14 cifre decimali). Se si utilizza una cifra eccessivamente ridotta, la differenza non sarà significativa e si dovrà riutilizzare il numero originale.