---
schema_version: "1"
id: a5c1771a18fec54e270190d91d318e7b6473664dbdc3ecd588d948a7f28fdb9e
title: Tableau Desktop 中包含第二個日期的分析
collection: tableau
version: current
locale: zh-tw
portal_url: https://docs.salesforce.com/tableau/current/zh-tw/prep/prep_tutorial_2nddateB.md
canonical_url: https://help.tableau.com/current/prep/zh-tw/prep_tutorial_2nddateB.htm
source_site: help.tableau.com
content_type: documentation
content_hash: 207b816fddd1dcddc71f3eccbcd788ce2d55214dfea7e9d28b74fdf606fc654d
description: "tutorial: analyze the second-date data set in Tableau Desktop."
---
[跳至主要內容](#main-content)

# Tableau Desktop 中包含第二個日期的分析

這是教程的第二個階段，並且假定第一個階段[使用 Tableau Prep 查找第二個日期](https://help.tableau.com/current/prep/zh-tw/prep_tutorial_2nddateA.htm)已完成。

在第一個階段中，我們採用原始資料集並對其進行調整來回答以下問題：

1. 每個駕駛員第一次和第二次違章相隔多長時間（以天數為單位）？
2. 比較第一次和第二次違章的罰款金額。這些金額是否相關？
3. 總體而言，哪個駕駛員支付的罰款最多？誰支付的最少？
4. 有多少駕駛員有過多種類型的違章？
5. 從未上過交通法規學習班的駕駛員的平均罰款金額是多少？

我們現在探討這些問題時，可以清晰地發現我們建立的第一個資料結構有一些優缺點。我們將返回到 Tableau Prep Builder 中並進行一些額外的重新調整，然後看看會對 Tableau Desktop 中同樣的分析產生怎樣的影響。最後，我們將探討 Tableau Desktop 獨有的將詳細資料層級 (LOD) 運算式與原始資料結合使用進行分析的方法。

本教程的目標是在一個真實場景的內容中呈現各種概念並演練各個選項 — 而不是規定式地確定哪一個是最好的。最後，您應該會對資料結構對計算和分析的影響有更深的認識，並更加熟悉 Tableau Prep 的各項功能以及 Tableau Desktop 中的計算。

**附註**：為完成本教程中的工作，您需要安裝 Tableau Prep Builder 並根據需要安裝 Tableau Desktop，並下載相關資料。  
  
若要在繼續本教學課程之前安裝 Tableau Prep 和 Tableau Desktop，請參閱 [Tableau Desktop 和 Tableau Prep 部署指南](https://help.tableau.com/current/desktopdeploy/zh-tw/desktop_deploy_welcome.htm#)。否則，您可以下載 [Tableau Prep](https://www.tableau.com/zh-tw/products/prep/download) 和 [Tableau Desktop](https://www.tableau.com/zh-tw/products/desktop/download) 免費試用版。  
  
資料集是在第一個階段中組建的 [Driver Infractions.tflx](https://mkt.tableau.com/PrepTutorials/Driver%20Infractions.tflx) 的輸出。

## Tableau Desktop 中的分析

既然我們已經設定了資料，我們就將其引入 Tableau Desktop。我們可以輕鬆地回答一些問題，但其他問題會涉及一些（或很多）計算。請嘗試下面的問題；如果遇到困難，您可以展開每個問題來瞭解有關如何繼續的基本資訊。

**附註：**您可以下載工作簿 [Driver Infractions.twbx](https://mkt.tableau.com/PrepTutorials/Driver%20Infractions.twbx)，在上下文中探討解決方案。請記住，可以透過一些替代方式來解讀分析或尋找答案。

1.每個駕駛員第一次和第二次違章相隔多長時間（以天數為單位）？

1. 為了在 Tableau Desktop 中回答此問題，我們將使用 DATEDIFF 函數。此函數採用三個參數 — 日期部分、開始日期和結束日期。由於我們想知道這些事件的間隔天數，因此將使用日期部分「day」。我們的開始日期和結束日期在資料集中為「**1st Infraction Date**」（第一次違章日期）和「**2nd Infraction Date**」（第二次違章日期）。
2. 計算為：
    
    **Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])`
3. 我們依據「**Driver ID**」（駕駛員 ID）將該計算繪製為橫條圖。請注意，7 名駕駛員沒有第二次違章，因此有 7 個 null 值。
    
    ![按違章間隔時間顯示的駕駛員橫條圖](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_1desktopI.png)

2.比較第一次和第二次違章的罰款金額。這些金額是否相關？

1. 為了在 Tableau Desktop 中回答此問題，我們將建立「**1st Fine Amount**」（第一次罰款金額）和 「**2nd Fine Amount**」（第二次罰款金額）的散點圖。透過將**「Driver ID」**（駕駛員 ID）放到「標記」卡上的「詳細資訊」架，我們可以為每名駕駛員建立一個標記。
2. 若要新增趨勢線，請使用左側窗格中的「分析」索引標籤，並顯示線性趨勢線。將游標暫停在趨勢線上，我們可以看到 R 平方值實際上為零，並且 p 值明顯高於任何臨界值。我們可以確定，第一次罰款金額和第二次罰款金額之間沒有相關性。
    
    若要在儀表板中使用此散點圖，則應移除趨勢線。

![按駕駛員 ID 顯示的第 1 次和第 2 次罰款金額的散佈圖，顯示趨勢線工具提示](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_1desktopII.png)

3.總體而言，哪個駕駛員支付的罰款最多？誰支付的最少？

如果想要更深入地進行分析，我們可能需要建立一些計算。

1. 為了在 Tableau Desktop 中回答此問題，我們需要將兩次違章的罰款新增到單一欄位中。由於某些駕駛員可能沒有第二次違章，我們需要使用零 null `ZN` 函數將「**2nd Fine Amount**」（第二次罰款金額）的任何 null 值轉換為零。若沒有第二次罰款，不這樣做會產生 null 值。
2. 計算為：
    
    **Total Amount Paid**（總支付金額）= `[1st Fine Amount] + ZN([2nd Fine Amount])`
3. 我們可以依據「**Driver ID**」（駕駛員 ID）繪製「**Total Amount Paid**」（總支付金額）橫條圖並對其進行排序。

![按駕駛員 ID 顯示的支付金額橫條圖，為支付金額顯示計算編輯器](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_1desktopIII.png)

4.有多少駕駛員有過多種類型的違章？

1. 為了在 Tableau Desktop 中回答此問題，我們需要執行一個更細緻的 `IF` 計算，比較第一次和第二次違規類型是否相同。如果相同，我們想要指派值「1」。如果不同，我們將指派「2」。由於我們僅關注多種類型的違章，因此系統會向其他任何結果（如為 null 的第二種違章類型）指派「1」。
2. 計算為：
    
    **Number of Infraction Types**（違章類型數量）=
    
    IF \[1st Infraction Type\]=\[2nd Infraction Type\] THEN 1 
    ELSEIF \[1st Infraction Type\]!= \[2nd Infraction Type\] THEN 2 
    ELSE 1 END
3. 然後，我們可以依據「**Driver ID**」（駕駛員 ID）繪製「**Number of Infraction Types**」（違章類型數量）橫條圖並對其進行排序。

![按駕駛員 ID 顯示的違章類型數量橫條圖，為違章類型數量顯示計算編輯器](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_1desktopIV.png)

5.從未上過交通法規學習班的駕駛員的平均罰款金額是多少？

1. 為了在 Tableau Desktop 中回答此問題，我們無法簡單地將總罰款金額除以二，因為某些駕駛員只有一次違章。我們也無法計算每個駕駛員的平均罰款並取這些值的平均值，因為對平均值進行平均計算可能會導致不一致。作為替代，我們需要計算從未上過交通法規學習班的駕駛員支付的總金額，然後除以與這些罰款關聯的總違章次數。
    
    1. 首先，我們需要確定是否每個駕駛員都有第二次違章。如果沒有第二次違章，則所有「2nd」欄位中的資訊都將為 null，我們可以利用這一事實並開始組建計算：
        
        `IFNULL([2nd Infraction Type], 'no')`
        
        這將返回違章類型（如果存在），或者如果沒有第二次違章，則返回「no」。
    2. 接著，我們需要將此資訊轉換為違章次數 1 或 2。如果 `IFNULL` 計算的結果為 「no」，則應將駕駛員標記為有一次罰款。對於任何其他結果，則應標記為有兩次罰款。計算為：
        
        **Number of Infractions**（違章次數）=
        
        IF IFNULL(\[2nd Infraction Type\], 'no') = 'no' THEN 1 
        ELSE 2 
        END
    3. 現在，我們需要考慮總罰款金額。與上面的問題 3 類似，我們將新增第一次和第二次罰款金額，並將第二次罰款金額放在 `ZN` 函數內。但是，由於我們想在整個資料集層級計算此值，因此最佳做法是在計算本身中指定彙總 SUM。計算為： 
        
        `SUM([1st Fine Amount]) + SUM( ZN([2nd Fine Amount]) )`
    4. 總而言之，我們將利用這個總罰款金額，並將其除以新的**「Number of Infractions」**（違章次數）計算欄位，從而確定平均罰款金額：
        
        **Average Fine**（平均罰款）= `( SUM([1st Fine Amount]) + SUM( ZN([2nd Fine Amount]) ) ) / SUM([Number of Infractions])`
2. 我們還需要篩選出曾經參加過交通法規學習班的駕駛員 — 但該資訊也跨兩個欄位存放。
    
    1. Tableau 在進行數值計算時非常高效。我們將用盡可能多可說明提高效能的數字表述這一點。為了合併這兩個欄位，我們將為每個欄位建立一個顯示為「Yes = 1」和「No = 0」的欄位（對於沒有第二次違章的駕駛員，null 也應 = 0）。透過對這些計算的結果求和，總值為 0 的任何駕駛員從未上過交通法規學習班（值 1 或 2 表示他們上過交通法規學習班的次數）。我們隨後可以進行篩選，以僅保留值為 0 的駕駛員。
    2. 這一次，我們將使用 `CASE` 語句，而不是 `IF`。這些語句的功能非常相似，但具有不同的語法。計算的開頭應如下所示：
        
        CASE \[1st Traffic School\]
        WHEN 'Yes' THEN 1
        WHEN 'No' THEN 
        ELSE 0
        END
    3. 然後，我們將為「2nd Traffic School」執行相同的操作。透過將每個 CASE 語句放在括弧內並在兩者之間新增一個加號，我們可以在同一計算中新增這兩段語句。移除一些分行符號，它看起來如下所示：
        
        **Number of Traffic School Attendances**（參加交通法規學習班次數）=
        
        (CASE \[1st Traffic School\] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
        +
        (CASE \[2nd Traffic School\] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
    4. 如果我們將**「Number of Traffic School Attendances」**（參加交通法規學習班次數）拖到「資料」窗格的「維度」區域（在線上方），則值 0–2 將變為離散。
    5. 現在，如果我們對**「Number of Traffic School Attendances」**（參加交通法規學習班次數）進行篩選，我們可以只選取 0，並且知道我們獲得了從未參加過交通法規學習班的駕駛員。
3. 為了回答原來的問題，我們只需將**「Average Fine」**（平均罰款）放到「標記」卡上的「文字」架。
    
    由於我們在計算中組建了彙總，因此膠囊上的彙總將為 AGG，我們無法對其進行變更。這是預期行為。

![平均支付金額的單一數字檢視，已開啟計算編輯器，以顯示參加交通法規學習班次數](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_1desktopV.png)

## 更進一步 — 樞紐的資料

儘管我們一直在處理的資料結構良好，可以解決與第一次和第二次違章特定相關的問題，但它並不是我們建議用於 Tableau Desktop 的標準結構。我們的分析背離與違章日期相關的基本問題越遠，用於將相關資訊合併為可用形式的計算就會變得越複雜。

通常，如果為同一類型的資料使用多個列存放資料（例如兩個列用於日期，兩個列用於罰款金額等），並且唯一的資訊存放在欄位名中（例如是第一次還是第二次違章），這就表明應該要對資料進行樞紐。

在 Tableau Prep Builder 中執行多重樞紐可以很好地處理此問題。我們可以從上一教程[使用 Tableau Prep 查找第二個日期](https://help.tableau.com/current/prep/zh-tw/prep_tutorial_2nddateA.htm)中建立的**「Driver Infraction」**（駕駛員違章）Tableau Prep 流程的結尾開始工作。

> [!TIP]
> 
> **提示**：請確保已返回 Tableau Prep，以進行後續步驟。

1. 從最後的清理步驟中，新增一個「Pivot」（樞紐）步驟，該步驟將按每個重複的欄位進行樞紐。使用「樞紐的欄位」區域右上角的加號 ![帶有加號的按鈕。](/tableau/current/zh-tw/prep/zh-tw/Img/prep_addicon.png) 圖示來新增更多「樞紐值」。每一組欄位（例如第一次和第二次罰款金額）應一起樞紐。
    
    有關樞紐的詳細資訊，請參閱[清理和調整資料](https://help.tableau.com/current/prep/zh-tw/prep_clean.htm#Pivot)。
2. 在「樞紐的欄位」區域中的「Pivot1 Names」（樞紐 1 名稱）欄下，按兩下每個值，並將其重新命名為 1st 和 2nd。
    
    ![Tableau Prep 中的樞紐 1 設定窗格，顯示五個樞紐](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_2desktop.png)

透過移除 null 日期以及重命名欄位並對其進行重新排序，可以對結果進行整理。

1. 在樞紐後面新增清理步驟。在**「Infraction Date」**（違章日期）欄中，以滑鼠右鍵按一下 null 條並選取「排除」。
2. 按兩下欄位名**「Pivot1 Names」**（樞紐 1 名稱），並將其重命名**「Infraction Number」**（違章次數）。
3. 視情況而定拖動資料以按如下方式對其進行重新排序：
    
    ![已樞紐和已清理資料的預覽](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_2desktopdata.png)

1. 依據新的樞紐的資料建立一個名為**「Pivoted Driver Infractions」**（樞紐的駕駛員違章）的輸出，並將其引入 Tableau Desktop。（在新增「輸出」步驟之後，不要忘記執行流程。）

現在，我們可以用這個樞紐的資料結構再次探討我們的五個問題；如果遇到困難，您可以展開每個問題來瞭解有關如何繼續操作的基本資訊。

**附註：**您可以下載完成的流程檔 [Pivoted Driver Infractions.tflx](https://mkt.tableau.com/PrepTutorials/Pivoted%20Driver%20Infractions.tflx) 來檢查您的工作，或者下載工作簿 [Pivoted Driver Infractions.twbx](https://mkt.tableau.com/PrepTutorials/Pivoted%20Driver%20Infractions.twbx) 在上下文中查看解決方案。請記住，可以透過一些替代方式來解讀分析或尋找答案。

1.每個駕駛員第一次和第二次違章相隔多長時間（以天數為單位）？

1. 為了在 Tableau Desktop 中回答此問題，就像我們對第一個資料集所做的那樣，我們將使用 `DATEDIFF` 函數。此函數需要一個開始日期和一個結束日期。此資訊存在於我們的資料中，但全部在一個欄位中。我們需要將其拉出到兩個欄位中。
    
    1. 建立兩個初始計算欄位：
        
        **1st Infraction Date**（第一次違章日期）= `IF [Infraction Number] = "1st" THEN [Infraction Date] END`
        
        **2nd Infraction Date**（第二次違章日期）= `IF [Infraction Number] = "2nd" THEN [Infraction Date] END`
    2. 由於我們想要確保這兩個欄位均可用于為每個駕駛員比較，我們需要將它們固定到**「Driver ID」**（駕駛員 ID）層級。
        
        **附註：**不相信我？嘗試按原樣對這兩個欄位進行 `DATEDIFF` 計算：**Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])`  
        您將在所有地方都獲得 null 結果，因為 Tableau 會嘗試跨類似於如下的資料結構進行比較：  
        ![顯示 null 結果的文字表](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_2desktopnulls.png)  
        在這裡，知道第一個日期的列不知道第二個日期，反之亦然。為了解決此問題，我們將使用「FIXED」詳細資料層級運算式將第一個和第二個日期強制與**「Driver ID」**（駕駛員 ID）相關。
    
    按如下方式編輯計算：
    
    **1st Infraction Date**（第一次違章日期）= `{ FIXED [Driver ID] : MIN ( IF [Infraction Number] = "1st" THEN [Infraction Date] END ) }`
    
    **2nd Infraction Date**（第二次違章日期）= `{ FIXED [Driver ID] : MIN ( IF [Infraction Number] = "2nd" THEN [Infraction Date] END ) }`
    
    **附註**：將原始 `IF` 計算內嵌在 LOD 運算式中時，必須對其進行彙總。我們可以使用任何將保留日期值的基本彙總（因此像 SUM、AVG 或 MIN 這樣的彙總有用，而 CNT 或 CNTD 則不行）。
    
    **附註**：也可以在 Tableau Prep Builder 中建立這些計算。有關 Prep 中 LOD 運算式的詳情，請參閱[建立詳細資料層級、排名和動態磚計算](https://help.tableau.com/current/prep/zh-tw/prep_calculations.htm)。
    
    8. 現在，我們可以按如下方式建立 `DATEDIFF` 計算：
        
        **Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])`
        
        - 如果我們想要查看週或月，只需修改日期部分（目前為 `'day'`）。
        - 也可以將 FIXED 計算直接放在 DATEDIFF 內，以為整個事件建立單一的計算： 
            
            DATEDIFF ( 'day', 
            
            { FIXED \[Driver ID\] : MIN ( IF \[Infraction Number\] = "1st" THEN \[Infraction Date\] END ) },
            
            { FIXED \[Driver ID\] : MIN ( IF \[Infraction Number\] = "2nd" THEN \[Infraction Date\] END ) }
            
            )
    9. 在欄上繪製**「違章間隔時間」**，並在列上繪製**「駕駛員 ID」**。

結果將與使用未樞紐資料結構的結果相同。

2.比較第一次和第二次違章的罰款金額。這些金額是否相關？

1. 為了在 Tableau Desktop 中回答此問題，我們將使用與上一個問題非常相似的邏輯。我們將使用**「Infraction Number」**（違章次數）來確定給定列是第一次違章還是第二次違章，然後相應拉出罰款金額。
    
    1. 如果我們只需要建立散點圖，則可以跳過 LOD 部分，只使用 `IF` 計算：
        
        **1st Fine Amount**（第一次罰款金額）= `IF [Infraction Number] = "1st" THEN [Fine Amount] END`
        
        **2nd Fine Amount**（第二次罰款金額）= `IF [Infraction Number] = "2nd" THEN [Fine Amount] END`
    2. 但是，如果我們想要進行比較並查看某個駕駛員第一次和第二次罰款之間的金額差異，我們會遇到像日期一樣的 null 問題。將這些計算封裝在 `FIXED` LOD 內不會有什麼壞處，因此從一開始這樣做或許會不錯：
        
        **1st Fine Amount**（第一次罰款金額）= `{ FIXED [Driver ID] : MIN ( IF [Infraction Number] = "1st" THEN [Fine Amount] END ) }`
        
        **2nd Fine Amount**（第二次罰款金額）= `{ FIXED [Driver ID] : MIN ( IF [Infraction Number] = "2nd" THEN [Fine Amount] END ) }`
        
        也可以在 Tableau Prep Builder 中建立這些計算。有關 Prep 中 LOD 運算式的詳情，請參閱[建立詳細資料層級、排名和動態磚計算](https://help.tableau.com/current/prep/zh-tw/prep_calculations.htm)。
    3. 建立具有**「第一次罰款金額」**（欄）和**「第二次罰款金額」**（列）的散點圖，並像以前一樣顯示線性趨勢線。

結果將與使用未樞紐資料結構的結果相同。

3.總體而言，哪個駕駛員支付的罰款最多？誰支付的最少？

1. 為了在 Tableau Desktop 中回答此問題，樞紐的資料結構非常理想。我們只需在橫條圖中顯示**「Driver ID」**（駕駛員 ID）和**「Fine Amount」**（罰款金額）。預設彙總已經是 SUM，因此將自動繪製駕駛員支付的總金額。

結果將與使用未樞紐資料結構的結果相同。

4.有多少駕駛員有過多種類型的違章？

1. 為了在 Tableau Desktop 中回答此問題，樞紐的資料結構非常理想。我們只需以橫條圖形式顯示**「Driver ID」**（駕駛員 ID）以及**「Infraction Type」**（違章類型）的「不重複計數」，就能得到答案。

結果將與使用未樞紐資料結構的結果相同。

5.從未上過交通法規學習班的駕駛員的平均罰款金額是多少？

1. 為了在 Tableau Desktop 中回答此問題，我們無法簡單地將總罰款金額除以二，因為某些駕駛員只有一次違章。我們也無法計算每個駕駛員的平均罰款並取這些值的平均值，因為對平均值進行平均計算可能會導致不一致。作為替代，我們需要計算從未上過交通法規學習班的駕駛員支付的總金額，然後除以與這些罰款關聯的總違章次數。
    
    1. 首先，我們需要確定是否每個駕駛員都有第二次違章。如果沒有第二次違章，則**「2nd Infraction Date」**（第二次違章日期）將為 null，我們可以利用這一事實並開始組建計算：
        
        `IFNULL(STR([2nd Infraction Date]), 'no')`
        
        這將返回第二次違章的日期（如果存在），或者如果沒有第二次違章，則返回 「no」。
        
        **附註：**此計算的 `STR` 部分是必需的，因為 `IFNULL` 需要在其參數中保持資料類型的一致性。由於我們想要為 null 值返回字串 「no」，因此也要將日期轉換為字串。
    2. 接著，我們需要將此資訊轉換為違章次數 1 或 2。如果 `IFNULL` 計算的結果為 「no」，則應將駕駛員標記為有一次罰款。對於任何其他結果，則應標記為有兩次罰款。計算為：
        
        **Number of Infractions**（違章次數）=
        
        IF IFNULL(STR(\[2nd Infraction Date\]), 'no')= 'no' THEN 1 
        ELSE 2 
        END
    3. 現在，我們需要考慮平均罰款金額。我們已經有了一個**「Fine Amount」**（罰款金額）欄位。我們只需將該欄位除以新的**「Number of Infractions」**（違章次數）欄位，同時將兩者都放在 SUM 內： 
        
        **Average Fine**（平均罰款）= `(SUM([Fine Amount]) / SUM([Number of Infractions])`
2. 我們還需要篩選出參加過交通法規學習班的駕駛員。看起來我們可以使用 **「Traffic School」**（交通法規學習班）欄位並對 **「Traffic School = no」**（交通法規學習班 = 無）進行篩選。但是，這將篩選與交通法規學習班無關的_違章行為_，而不是從未上過交通法規學習班的_駕駛員_。若一名駕駛員因為一次違章上過交通法規學習班，但沒有因為另一次上過，則我們不需要在此處考慮其中任何一次違章 — 該駕駛員已上過交通法規學習班，因此不符合問題的參數。
    
    我們需要做的是篩選出參加過交通法規學習班的任何駕駛員。就資料而言，我們想要篩選出任何列上**「Traffic School」**（交通法規學習班）為「Yes」（是）的任何駕駛員，無論其與哪次違章相關聯。讓我們分階段組建計算，並使用一個簡單的檢視來說明跟蹤所發生的情況：
    
    1. 首先，我們想要知道駕駛員的「Traffic School」（交通法規學習班）是否為「Yes」（是）。將**「Driver ID」**（駕駛員 ID）拖到「列」，並將**「Traffic School」**（交通法規學習班）拖到「欄」。我們將獲得一個文字表，其中預留位置「Abc」文字表示每個駕駛員的相關值。
    2. 接著，我們想要組建一個計算，該計算將確定**「Traffic School」**（交通法規學習班）的值是否為「Yes」（是）。計算的第一個階段是：
        
        **Attended Traffic School**（已參加交通法規學習班）= `CONTAINS([Traffic School), 'Yes')`
        
        如果我們將**「Attended Traffic School」**（已參加交通法規學習班）拖到「標記」卡上的「顏色」架，我們會看到它準確地針對「No」（否）欄中的每個標記標為「False」，並針對「Yes」（是）欄中的每個標記標為「True」。
        
        ![視覺效果，其中「否」欄中的每個標記都具有「False」標籤，「是」欄中的每個標記都具有「True」標籤。](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_pivotedV2.png "按「Traffic School」（交通法規學習班）列出的「Driver ID」（駕駛員 ID）的檢視，「Attended Traffic School」（已參加交通法規學習班）放在「顏色」上")
    3. 但是，我們真正需要的是位於_駕駛員_（而不是_違章_）層級的此資訊。嘗試在與基本資料結構不同的詳細資料層級計算結果時，LOD 運算式非常適合。我們將此運算式設為 `FIXED` LOD 運算式。但是，正如我們所知，必須對 LOD 的彙總運算式進行彙總。以前，我們使用過 MIN。它在這裡是否有用？我們將計算修改為： 
        
        **Attended Traffic School**（已參加交通法規學習班）= `{ FIXED [Driver ID] : MIN( CONTAINS([Traffic School], 'Yes'))}`
        
        ![按「Traffic School」（交通法規學習班）列出的「Driver ID」（駕駛員 ID）的檢視，「Attended Traffic School」（已參加交通法規學習班）放在「顏色」上](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_pivotedV3.png)
        
        在檢視中應用該變更之後，我們看到了與預期相反的結果。具有「no」值的任何駕駛員全部被標記為「False」。相反，我們希望為該駕駛員的每條記錄將「Yes」標記為「True」。MIN 在這裡做了什麼？它按字母順序選取第一個回應，即 「no」。
    4. 如果我們將其變更為 MAX，將會怎麼樣？該函數是否會按字母順序獲取最後一個回應？我們將計算修改為： 
        
        **Attended Traffic School**（已參加交通法規學習班）= `{ FIXED [Driver ID] : MAX ( CONTAINS( [Traffic School], 'Yes') ) }`
        
        ![按「Traffic School」（交通法規學習班）列出的「Driver ID」（駕駛員 ID）的檢視，「Attended Traffic School」（已參加交通法規學習班）放在「顏色」上](/tableau/current/zh-tw/prep/zh-tw/Img/prep_tutorial_2d_pivotedV4.png)
        
        我們得到了想要的結果：如果駕駛員在資料中的任何位置有「Yes」，他們會因為參加過交通法規學習班而被標記為「True」，即使對於不涉及交通法規學習班的違章也是如此。
    5. 如果我們將**「Attended Traffic School」**（已參加交通法規學習班）拖到「篩選器」架並僅選取「False」，將只會剩下從未參加過交通法規學習班的駕駛員。
3. 為了回答原來的問題，在篩選器就位的情況下，我們只需將**「Average Fine」**（平均罰款）放到「標記」卡上的「文字」架。由於我們在計算中組建了彙總，因此欄位上的彙總將為 AGG，我們無法對其進行變更。這是預期行為。

結果將與使用未樞紐資料結構的結果相同。

### 樞紐資料的優點

如果知道我們只需要回答可以使用教程中的原始資料結構輕鬆回答的問題，我們可以繼續使用該結構。不過，樞紐的資料格式更加靈活。即使它需要一些計算，但在計算就位之後，產生的資料集將非常適合於回答更廣泛的問題。

## 再進一步 — 只使用計算

若無法存取 Tableau Prep Builder，該怎麼辦？如果被迫使用原始資料，您是否完全不走運？根本不會！

Tableau Desktop 和 LOD 運算式可以回答所有分析問題。如果我們連線到原始的 [**Traffic Violations.xlsx**](https://mkt.tableau.com/PrepTutorials/Traffic%20Violations.xlsx)，它看起與已樞紐資料集非常相似 — 只是沒有重要的**「Infraction Number」**（違章次數）欄位。我們將需要透過 LOD 運算式類比彙總步驟的輸出。

**附註：**您可以下載工作簿 [LOD Driver Infractions.twbx](https://mkt.tableau.com/PrepTutorials/LOD%20Driver%20Infractions.twbx)，在上下文中探討解決方案。請記住，可以透過一些替代方式來解讀分析或尋找答案。

1.每個駕駛員第一次和第二次違章相隔多長時間（以天數為單位）？

1. 為了在 Tableau Desktop 中回答此問題，我們將再次使用 `DATEDIFF` 函數。此函數需要一個開始日期和一個結束日期。此資訊存在於我們的資料中，但全部在一個欄位中。我們需要將其拉出到兩個欄位中。由於我們想要確保這兩個欄位均可用于為每個駕駛員比較，我們需要將它們固定到**「Driver ID」**（駕駛員 ID）層級。
    
    1. 為了查找第一次違章日期，我們將使用計算：
        
        **1st Infraction**（第一次違章）= `{ FIXED [Driver ID] : MIN ( [Infraction Date] ) }`
    2. 我們將分階段執行第二次違章日期相關操作。
        
        1. 首先，我們需要只查看比第一個日期大的日期：
            
            `IF [Infraction Date] > [1st Infraction] THEN [Infraction Date] END`
        2. 但這將列出第一次違章之後_每次_違章，而我們只需要第二次違章。因此我們需要這些日期中最小的日期。將整個計算放在 MIN 內：
            
            `MIN( IF [Infraction] : [1st Infraction] THEN [Infraction Date] END )`
        3. 我們還想要為每個駕駛員重新計算第二次違章日期。這就是 LOD 運算式的用武之地。我們會將此計算固定到**「Driver ID」**（駕駛員 ID）層級：
            
            **2nd Infraction**（第二次違章）= `{ FIXED [Driver ID] : MIN ( IF [Infraction Date] > [1st Infraction] THEN [Infraction Date] END ) }`
    3. 現在我們可以建立 `DATEDIFF` 計算：
        
        **Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction], [2nd Infraction])`

結果將與使用其他兩個資料結構的結果相同。

2.比較第一次和第二次違章的罰款金額。這些金額是否相關？

1. 為了在 Tableau Desktop 中回答此問題，我們將使用此問題的樞紐資料版本相似的邏輯。我們將使用為問題 I 建立的**「1st Infraction」**（第一次違章）和**「2nd Infraction」**（第二次違章）來確定給定列是第一次違章還是第二次違章，然後相應拉出罰款金額。
    
    1. 如果我們只需要建立散點圖，則可以跳過 LOD 部分，只使用 `IF` 計算：
        
        **1st Fine Amount**（第一次罰款金額）= `IF [1st Infraction] = [Infraction Date] THEN [Fine Amount] END`
        
        **2nd Fine Amount**（第二次罰款金額）= `IF [2nd Infraction] = [Infraction Date] THEN [Fine Amount] END`
    2. 但是，如果我們想要進行比較並查看某個駕駛員第一次和第二次罰款之間的金額差異，我們會遇到像第一個資料結構中一樣的 null 問題。將這些計算封裝在 FIXED LOD 內不會有什麼壞處，因此從一開始這樣做或許會不錯：
        
        **1st Fine Amount**（第一次罰款金額）= ``{ FIXED [Driver ID] : MIN ( `IF [1st Infraction] = [Infraction Date] THEN [Fine Amount] END` ) }``
        
        **2nd Fine Amount**（第二次罰款金額）= ``{FIXED [Driver ID] : MIN( `IF [2ndInfraction] = [Infraction Date] THEN [Fine Amount] END` ) }``

結果將與使用其他兩個資料結構的結果相同。

3.總體而言，哪個駕駛員支付的罰款最多？誰支付的最少？

1. 為了在 Tableau Desktop 中回答此問題，我們需要瞭解有關僅 LOD 方法的一些資訊。使用 Tableau Prep 的兩種方法都會為駕駛員篩選出不是第一次或第二次違章的記錄。Tableau Desktop 中的 LOD 方法會保留所有記錄。這意味著，如果我們按**「Driver ID」**（駕駛員 ID）建立**「SUM(Amount Paid)」**的視覺化項，僅 Tableau Desktop 版本將為違章超過兩次的駕駛員顯示更高的金額。若要從與其他方法匹配的完整資料中獲取**「Total Amount Paid」**（總支付金額）值，而不是使用原始**「Fine Amount」**（罰款金額）欄位，則我們需要像使用第一個資料結構所做的那樣將第一次和第二次罰款加總。
2. 使用我們為問題 2 建立的欄位，我們將新增兩個罰款金額。`ZN`  是必要的，以防止任何只有一次違規的司機出現無效結果。計算為： 
    
    **Total Amount Paid**（總支付金額）= `[1st Fine Amount] + ZN([2nd Fine Amount])`

結果將與使用其他兩個資料結構的結果相同。

4.有多少駕駛員有過多種類型的違章？

1. 為了在 Tableau Desktop 中回答此問題，我們不能簡單地顯示**「司機 ID」**和**「違規類型」**的不重複計數。由於此資料集有超過第二次的違章，因此某些駕駛員可能有兩種以上的違章類型。為了使結果與其他方法相符，我們需要將範圍限制為僅包含前兩次違章。

1. 我們可以拉出第一次和第二次違章類型，將這些類型放在 LOD 運算式中，使它們 `FIXED` （固定）到駕駛員層級，然後使用 `IF` 計算來對類型計數：
    
    1. **1st Infraction Type**（第一次違章類型）= `{ FIXED [Driver ID] : MIN ( IF [1st Infraction] = [Infraction Date] THEN [Infraction Type] END ) }`
    2. **2nd Infraction Type**（第二次違章類型）= `{ FIXED [Driver ID] : MIN ( IF [2nd Infraction] = [Infraction Date] THEN [Infraction Type] END ) }`
    3. **Number of Infraction Types**（違章類型數量）=
        
        IF \[1st Infraction Type\] = \[2nd Infraction Type\] THEN 1 
        ELSEIF \[1st Infraction Type\] != \[2nd Infraction Type\] THEN 2
        ELSE 1 END 
        
        **附註：**也可以透過直接將初始計算內嵌在較大的計算中，以單一欄位的形式建立多個這樣的計算。此處的合併計算將如下所示：  
        `IF   {FIXED [Driver ID] : MIN(IF [1st Infraction]=[Infraction Date] THEN [Infraction Type] END)}   =   {FIXED [Driver ID] : MIN(IF [2nd Infraction]=[Infraction Date] THEN [Infraction Type] END)}   THEN 1      ELSEIF   {FIXED [Driver ID] : MIN(IF [1st Infraction]=[Infraction Date] THEN [Infraction Type] END)}   !=   {FIXED [Driver ID] : MIN(IF [2nd Infraction]=[Infraction Date] THEN [Infraction Type] END)}   THEN 2      ELSE 1   END`  
          
        理解起來有點困難，但如果願意使用的話，它確實有用。（請注意，分行符號和一些空格不會影響 Tableau 解讀計算的方式。）
2. 然後，我們可以依據「**Driver ID**」（駕駛員 ID）繪製「**Number of Infraction Types**」（違章類型數量）橫條圖並對其進行排序。

結果將與使用其他兩個資料結構的結果相同。

5.從未上過交通法規學習班的駕駛員的平均罰款金額是多少？

1. 為了在 Tableau Desktop 中回答此問題，我們無法簡單地將總罰款金額除以二，因為某些駕駛員只有一次違章。我們也無法計算每個駕駛員的平均罰款並取這些值的平均值，因為對平均值進行平均計算可能會導致不一致。作為替代，我們需要計算從未上過交通法規學習班的駕駛員支付的總金額，然後除以與這些罰款關聯的總違章次數。
    
    1. 首先，我們需要確定是否每個駕駛員都有第二次違章。如果沒有第二次違章，則所有「2nd」欄位中的資訊都將為 null，我們可以利用這一事實並開始組建計算：
        
        `IFNULL([2nd Infraction Type], 'no')`
        
        這將返回違章類型（如果存在），或者如果沒有第二次違章，則返回「no」。
    2. 接著，我們需要將此資訊轉換為違章次數 1 或 2。如果 `IFNULL` 計算的結果為 「no」，則應將駕駛員標記為有一次罰款。對於任何其他結果，則應標記為有兩次罰款。計算為：
        
        **Number of Infractions**（違章次數）=
        
        IF IFNULL(\[2nd Infraction Type\], 'no') = 'no' THEN 1
        ELSE 2
        END
    3. 對於「Total Amount Paid」（總支付金額），我們可以使用問題 3 中的計算。總而言之，我們將利用這個總罰款金額，並將其除以新的**「Number of Infractions」**（違章次數）計算欄位，從而確定平均罰款金額：
        
        **Average Fine**（平均罰款）= `SUM([Total Amount Paid]) / SUM([Number of Infractions])`
2. 我們還需要篩選出參加過交通法規學習班的駕駛員。由於此資料集包含一些有第三次或第四次違章的駕駛員，因此我們無法使用與樞紐資料結構相同的方法。相反，我們將採用與未樞紐資料相同的方法，總結如下：
    
    1. 首先，我們需要組建兩個計算，確定第一次和第二次違章是否涉及交通法規學習班： 
        
        **1st Traffic School**（第一次交通法規學習班）= `{ FIXED [Driver ID] : MIN (IF [1st Infraction] = [Infraction Date] THEN [Traffic School] END ) }`
        
        **2nd Traffic School**（第二次交通法規學習班）= `{ FIXED [Driver ID] : MIN (IF [2nd Infraction] = [Infraction Date] THEN [Traffic School] END ) }`
    2. 然後，我們將新增這些值來獲取參加交通法規學習班的總次數： 
        
        **Number of Traffic School Attendances**（參加交通法規學習班次數）=
        
        (CASE \[1st Traffic School\] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
        +
        (CASE \[2nd Traffic School\] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
    3. 如果我們將**「Number of Traffic School Attendances」**（參加交通法規學習班次數）拖到「資料」窗格的「維度」區域，則值 0–2 將變為離散。
    4. 現在，如果我們對「**Number of Traffic School Attendances**」（參加交通法規學習班次數）進行篩選，我們可以只選取 0，並且知道我們獲得了從未參加過交通法規學習班的駕駛員。
3. 為了回答原來的問題，我們只需將**「Average Fine」**（平均罰款）放到「標記」卡上的「文字」架。由於我們在計算中組建了彙總，因此欄位上的彙總將為 AGG，我們無法對其進行變更。這是預期行為。

結果將與使用其他兩個資料結構的結果相同。

請務必記住，此解決方案包含大量的嵌套計算和 LOD 運算式。視資料集的大小以及資料集的複雜性而定，可能會出現效能問題。

## 對各種方法的反思

那麼您應該採用哪種方法呢？這完全取決於您，並且工具任由您隨意使用。

- 如果您想要避開 LOD，則可以使用資料調整解決方案，儘管對於某些分析（[Tableau Desktop 中的分析](#Desktop)）計算可能是必需的。
- 如果您能夠調整資料並且熟悉計算（包括 LOD），則中間型選項可以提供最好的靈活性（[更進一步 — 樞紐的資料](#Further)）。
- 如果您熟悉 LOD、對效能的影響較小，並且/或者您無法存取 Tableau Prep，則單獨使用 LOD 解決此問題是可行的選項（[再進一步 — 只使用計算](#Furtherer)）。

至少，它對於瞭解 Tableau Prep 中的彙總和 Tableau Desktop 中的詳細資料層級運算式如何相互關聯以及會對資料分析產生怎樣的影響是有價值的。如同 Tableau 中的大多數功能一樣，執行任何操作的方法都有多種。探索各種各樣的選項可以幫助將概念聯係在一起，讓您能挑選最適合於自己的解決方案。

使用的計算：

### Driver Infractions（駕駛員違章）

- **Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])`
- **Total Amount Paid**（總支付金額）=`[1st Fine Amount] + ZN([2nd Fine Amount])`
- **Number of Infraction Types**（違章類型數量）= `IF [1st Infraction Type]=[2nd Infraction Type] THEN 1 ELSEIF [1st Infraction Type]!= [2nd Infraction Type] THEN 2 ELSE 1 END`
- **Number of Infractions**（違章次數）= `IF IFNULL([2nd Infraction Type], 'no') = 'no' THEN 1 ELSE 2 END`
- **Average Fine**（平均罰款）= `( SUM([1st Fine Amount]) + SUM( ZN([2nd Fine Amount]) ) ) / SUM([Number of Infractions])`
- **Number of Traffic School Attendances**（參加交通法規學習班次數）= `(CASE [1st Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END) + (CASE [2nd Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)`

### Pivoted Driver Infractions（樞紐的駕駛員違章）

- **1st Infraction**（第一次違章）= `{FIXED [Driver ID] : MIN(IF [Infraction Number] = "1st" THEN [Infraction Date] END)}`
- **2nd Infraction**（第二次違章）= `{FIXED [Driver ID] : MIN(IF [Infraction Number] = "2nd" THEN [Infraction Date] END)}`
- **Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction], [2nd Infraction])`
- **1st Fine Amount**（第一次罰款金額）= `{FIXED [Driver ID] : MIN( IF [Infraction Number] = "1st" THEN [Fine Amount] END ) }`
- **Number of Infractions**（違章次數）= `IF IFNULL(STR([2nd Infraction]), 'no')= 'no' THEN 1 ELSE 2 END`
- **Average Fine**（平均罰款）= `SUM([Fine Amount])/SUM([Number of Infractions])`
- **Attended Traffic School**（已參加交通法規學習班）= `{ FIXED [Driver ID] : MAX( CONTAINS([Traffic School], 'Yes'))}`

### LOD Driver Infractions（LOD 駕駛員違章）

- **1st Infraction**（第一次違章）= `{FIXED [Driver ID] : MIN([Infraction Date])}`
- **2nd Infraction**（第二次違章）= `{ FIXED [Driver ID] : MIN( IF [Infraction Date] > [1st Infraction] THEN [Infraction Date] END ) }`
- **Time Between Infractions**（違章間隔時間）= `DATEDIFF('day', [1st Infraction], [2nd Infraction])`
- **1st Fine Amount**（第一次罰款金額）= `{FIXED [Driver ID] : MIN( IF [1st Infraction] = [Infraction Date] THEN [Fine Amount] END ) }`
- **2nd Fine Amount**（第二次罰款金額）= `{FIXED [Driver ID] : MIN( IF [2nd Infraction] = [Infraction Date] THEN [Fine Amount] END ) }`
- **Total Amount Paid**（總支付金額）= `[1st Fine Amount] + ZN([2nd Fine Amount])`
- **1st Infraction Type**（第一次違章類型）= `{FIXED [Driver ID] : MIN( IF [1st Infraction] = [Infraction Date] THEN [Infraction Type] END ) }`
- **2nd Infraction Type**（第二次違章類型）= `{FIXED [Driver ID] : MIN( IF [2nd Infraction] = [Infraction Date] THEN [Infraction Type] END ) }`
- **Number of Infraction Types**（違章類型數量）= `IF [1st Infraction Type]=[2nd Infraction Type] THEN 1 ELSEIF [1st Infraction Type]!= [2nd Infraction Type] THEN 2 ELSE 1 END`
- **Number of Infractions**（違章次數）= `IF IFNULL([2nd Infraction Type], 'no') = 'no' THEN 1 ELSE 2 END`
- **Average Fine**（平均罰款）= `SUM ([Total Amount Paid]) / SUM([Number of Infractions])`
- **1st Traffic School**（第一次交通法規學習班）= `{FIXED [Driver ID] : MIN (IF [1st Infraction] = [Infraction Date] THEN [Traffic School] END ) }`
- **2nd Traffic School**（第二次交通法規學習班）= `{FIXED [Driver ID] : MIN (IF [2nd Infraction] = [Infraction Date] THEN [Traffic School] END ) }`
- **Number of Traffic School Attendances**（參加交通法規學習班次數）= `(CASE [1st Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END) + (CASE [2nd Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)`

**附註：**特別感謝 Ann Jackson 的 Workout Wednesday 主題 [Do Customers Spend More on Their First or Second Purchase?（客戶在第一次或第二次購買時是否花費更多？）](https://www.workout-wednesday.com/2018/06/13/week-24-do-customers-spend-more-on-their-first-or-second-purchase/)以及 Andy Kriebel 的 Tableau Prep 技巧 [Returning the First and Second Purchase Dates（返回第一次和第二次購買日期）](https://www.vizwiz.com/2018/06/first-second-purchase.html?m=1)，這些文章為本教程提供了最初的靈感。按一下這些連結會使您離開 Tableau 網站。Tableau 對於外部提供者所維護之頁面的準確性或新鮮度不擔負任何責任。如果您對內容有疑問，請聯絡其擁有者。