# 配對間隔和反覆載入

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

## 使用 IntervalMatch() 前置詞

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

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

請執行下列動作：

1. 建立新的應用程式並命名。

2. 在資料載入編輯器中新增新的指令碼區段。

3. 叫用區段 Events。

4. 在右側功能表的 DataFiles 之下，按一下選取資料。

5. 上傳然後選取 Events.txt。

6. 在 選取資料來源 視窗中，按一下 新增。

7. 上傳然後選取 Intervals.txt。

8. 在 選取資料來源 視窗中，按一下 新增。

9. 在指令碼中，將第一個表格命名為事件，然後將第二個表格命名為 Intervals。

10. 在指令碼的結尾處新增 IntervalMatch 以建立第三個表格，該表格橋接最初的兩個表格：

    ```
    BridgeTable:
    IntervalMatch (EventDate)
    LOAD distinct IntervalBegin, IntervalEnd
    Resident Intervals;
    ```

11. 您的指令碼應如下所示：

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

12. 按一下載入資料。

13. 開啟資料模型檢視器。資料模型應如下所示：

    資料模型： Events、BridgeTable、Intervals 和 $Syn1 表格

    資料模型： Events、BridgeTable、Intervals 和 $Syn1 表格

    資料模型： EventsEvents、BridgeTableBridgeTable、IntervalsIntervals 和 $Syn1$Syn1 表格 ![資料模型：事件、BridgeTable、間隔和 $Syn1 表格。](https://help.qlik.com/zh-TW/cloud-services/Subsystems/Hub/Content/Resources/Images/tutorial-interval-match-prefix.png)

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

    基本表格包括：

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

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

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

資訊備註若要進一步瞭解 IntervalMatch()，請在 Qlik Community 中參閱此篇部落格貼文：[Using IntervalMatch()](https://community.qlik.com/t5/Qlik-Design-Blog/Using-IntervalMatch/ba-p/1475510)

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

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

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

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

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

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

請執行下列動作：

1. 使用下列指令碼取代現有的 Bridgetable 陳述式：
   ```
   BridgeTable:
   LOAD distinct * Where Exists(EventDate);
   LOAD IntervalBegin + IterNo() - 1 as EventDate, IntervalID
       Resident Intervals
       While IntervalBegin + IterNo() - 1 <= IntervalEnd;
   ```
2. 按一下載入資料。
3. 開啟資料模型檢視器。資料模型應如下所示：

   資料模型： Events、BridgeTable 和 Intervals 表格

   資料模型： Events、BridgeTable 和 Intervals 表格

   資料模型： EventsEvents、BridgeTableBridgeTable 和 IntervalsIntervals 表格 ![資料模型：事件、BridgeTable 和間隔表格。](https://help.qlik.com/zh-TW/cloud-services/Subsystems/Hub/Content/Resources/Images/ui_gen_Intervalmatch2.png)

   一般而言，採用三個表格的解決方案是最佳方案，因為它允許間隔與事件之間存在多對多關係。但是有一種常見的情況，您知道一個事件只能屬於一個單一間隔。在此情況下，橋接表格並非必要。IntervalID 可以直接儲存在事件表格中。要執行此操作，有多種方法，最有用的方法就是將 Bridgetable 聯結到 Events 表格中。
4. 將下列指令碼新增至指令碼結尾：
   ```
   Join (Events)
   LOAD EventDate, IntervalID
   Resident BridgeTable;
    
   Drop Table BridgeTable;
   ```
5. 按一下載入資料。
6. 開啟資料模型檢視器。資料模型應如下所示：

   資料模型： Events 和 Intervals 表格

   資料模型： Events 和 Intervals 表格

   資料模型： EventsEvents 和 IntervalsIntervals 表格 ![資料模型：事件和間隔表格。](https://help.qlik.com/zh-TW/cloud-services/Subsystems/Hub/Content/Resources/Images/ui_gen_Intervalmatch3.png)

## 開放和封閉的間隔

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

* 如果結束點包括在間隔內，則為封閉間隔：

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

  ]a,b[ = {x ∈ ℝ ∣ a &lt; x &lt; b}
* 如果只有一個結束點包括在間隔內，則為半開放間隔：

  [a,b[ = {x ∈ ℝ ∣ a ≤ x &lt; b}

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

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

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

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

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