跳到主要內容

配對間隔和反覆載入

LOADSELECT 陳述式的 Intervalmatch 前置詞是用於將離散數值連結到一或多個數值間隔。這是非常強大的功能,例如可用於生產等環境中。

使用 IntervalMatch() 前置詞

最基本的間隔配對是當您在一個表格中擁有一系列數字或日期 (事件),在另一個表格中擁有一系列間隔。您的目標是連結兩個表格。一般而言,這是多對多關係,即一個間隔包含位於其中的多個日期,並且一個日期也同屬於多個間隔。為了解決這個問題,您需要在兩個原始表格之間建立橋接表格。有多種方法可執行此操作。

Qlik Sense 中解決此問題的最簡單方法是在 LOADSELECT 陳述式前面加上 IntervalMatch() 前置詞。LOAD/SELECT 陳述式只需包含兩個欄位,即定義間隔的 FromTo 欄位。IntervalMatch() 前置詞將產生已載入間隔與之前載入的數字欄位之間的所有組合,指定為該前置詞的參數。

  1. 建立新的應用程式並命名。
  2. 資料載入編輯器中新增新的指令碼區段。
  3. 叫用區段 Events
  4. 在右側功能表的 DataFiles 之下,按一下選取資料

  5. 上傳然後選取 Events.txt
  6. 從以下項目選取資料視窗中,按一下插入指令碼
  7. 上傳然後選取 Intervals.txt
  8. 從以下項目選取資料視窗中,按一下插入指令碼
  9. 在指令碼中,將第一個表格命名為事件,然後將第二個表格命名為 Intervals
  10. 在指令碼的結尾處新增 IntervalMatch 以建立第三個表格,該表格橋接最初的兩個表格:
  11. BridgeTable: IntervalMatch (EventDate) LOAD distinct IntervalBegin, IntervalEnd Resident Intervals;
  12. 您的指令碼應如下所示:
  13. Events: 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. 按一下載入資料
  15. 開啟資料模型檢視器。資料模型應如下所示:
  16. 資料模型: EventsBridgeTableIntervals$Syn1 表格

    資料模型:

    資料模型包含一個複合索引鍵 (IntervalBeginIntervalEnd 欄位),該索引鍵會將自身顯示為 Qlik Sense 合成鍵。

    基本表格包括:

    • 每個事件只包含一個記錄的 Events 表格。
    • 每個間隔只包含一個記錄的 Intervals 表格。
    • 每個事件和間隔組合只包含一個記錄、並且連結之前兩個表格的橋接表格。

    請注意,如果間隔彼此重疊,一個事件可能同時屬於多個間隔。一個間隔顯然同時包括多個事件。

    本資料模型是一個標準化的精簡模型,是您的最佳選擇。Events 表格和 Intervals 表格均保持不變,並包含記錄的原始數值。在這些表格中進行的所有 Qlik Sense 計算,例如 Count(EventID),將正常工作並正確評估。

資訊備註若要進一步瞭解 IntervalMatch(),請在 Qlik Community 中參閱此篇部落格貼文:使用 IntervalMatch()

使用 While 迴圈和反覆載入 IterNo()

您可使用 While 迴圈和 IterNo() 得到幾乎一樣的橋接表格,該表格在間隔的上下限之間建立可列舉數值。

LOAD 陳述式內的迴圈可使用 While 子句建立。例如︰

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

只要 While 子句中的運算式為 true,此 LOAD 陳述式將重複每個輸入記錄並反覆載入。IterNo() 函數在首次反覆中返回「1」,在第二次中返回「2」,以此類推。

您有間隔的主要索引鍵 IntervalID,因此在指令碼中唯一的不同就是橋接表格的建立方式:

  1. 使用下列指令碼取代現有的 Bridgetable 陳述式:
  2. BridgeTable: LOAD distinct * Where Exists(EventDate); LOAD IntervalBegin + IterNo() - 1 as EventDate, IntervalID     Resident Intervals     While IntervalBegin + IterNo() - 1 <= IntervalEnd;

  3. 按一下載入資料
  4. 開啟資料模型檢視器。資料模型應如下所示:
  5. 資料模型: EventsBridgeTableIntervals 表格

    資料模型:

    一般而言,採用三個表格的解決方案是最佳方案,因為它允許間隔與事件之間存在多對多關係。但是有一種常見的情況,您知道一個事件只能屬於一個單一間隔。在此情況下,橋接表格並非必要。IntervalID 可以直接儲存在事件表格中。要執行此操作,有多種方法,最有用的方法就是將 Bridgetable 聯結到 Events 表格中。

  6. 將下列指令碼新增至指令碼結尾:
  7. Join (Events) LOAD EventDate, IntervalID Resident BridgeTable;   Drop Table BridgeTable;

  8. 按一下載入資料
  9. 開啟資料模型檢視器。資料模型應如下所示:
  10. 資料模型: EventsIntervals 表格

    資料模型:

開放和封閉的間隔

間隔是開放還是封閉由結束點確定,具體要看結束點是否包括在間隔內。

  • 如果結束點包括在間隔內,則為封閉間隔:
  • [a,b] = {x ∈ ℝ ∣ a ≤ x ≤ b}

  • 如果結束點不包括在間隔內,則為開放間隔:
  • ]a,b[ = {x ∈ ℝ ∣ a < x < b}

  • 如果只有一個結束點包括在間隔內,則為半開放間隔:
  • [a,b[ = {x ∈ ℝ ∣ a ≤ x < b}

如果遇到間隔重疊且一個數字可以同時屬於多個間隔的情況,您通常需要使用封閉間隔。

但在某些情況下,您不想要重疊間隔,您想讓一個數字只屬於一個間隔。因此,如果一個點位於一個間隔的結尾處,同時也位於下一個間隔的開頭,您就會遇到問題。這樣的數值將同屬於兩個間隔。因此,您想要半開放間隔。

此問題的實際解決方法是從所有間隔的結束值中減去少量值,這樣便可以建立封閉但不重疊的間隔。如果您的數值是日期,最簡單的方法就是使用函數 DayEnd(),該函數會返回當日的最後一毫秒:

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

您也可以手動減去少量值。如果您這麼做了,請確保減去的數量不至於太少,因為運算會四捨五入至 52 個有效二進位數字 (14 個小數位數)。如果您使用的量太小,差別不會很明顯,您將用回原來的數值。