如果您有 SQL 背景,可能很好奇 Looker 如何產生 SQL。從根本上來說,Looker 是一種工具,可產生 SQL 查詢並提交至資料庫連線。Looker 會根據 LookML 專案建立 SQL 查詢,說明資料庫中資料表和資料欄之間的關係。瞭解 Looker 如何產生查詢,有助於您進一步瞭解 LookML 程式碼如何轉換為有效率的 SQL 查詢。
每個 LookML 參數都會控制 Looker 產生 SQL 的某個層面,方法是變更查詢的結構、內容或行為。本頁面說明 Looker 產生 SQL 的原則,但不會詳細介紹所有 LookML 元素。如要瞭解 LookML 參數,建議先參閱 LookML 快速參考說明文件頁面。
查看查詢
在已儲存的「Look」或「Explore」中,您可以使用「資料」面板中的「SQL」分頁,查看 Looker 傳送至資料庫以取得資料的內容。您也可以使用「SQL」分頁底部的「在 SQL Runner 中開啟」和「在 SQL Runner 中說明」連結,在 SQL Runner 中查看查詢,或查看查詢的資料庫說明計畫。
如要進一步瞭解 SQL Runner,請參閱「SQL Runner 基礎知識」說明文件頁面。如要進一步瞭解如何使用 SQL Runner 最佳化查詢,請參閱「如何使用 EXPLAIN 最佳化 SQL」社群貼文。
Looker 查詢的標準形式
Looker 的 SQL 查詢一律採用下列格式。
SELECT
<dimension>, <dimension>, ...
<measure>, <measure>, ...
FROM <explore>
LEFT JOIN <view> ON ...
LEFT JOIN <view> ON ...
WHERE (<dimension_filter_expression>) AND (<dimension_filter_expression>) AND ...
GROUP BY <dimension>, <dimension>, <dimension>, ...
HAVING <measure_filter_expression> AND <measure_filter_expression> AND ...
ORDER BY <dimension> | <measure>
LIMIT <limit>
LookML 專案會定義 SQL 查詢中參照的所有維度、指標、探索和檢視區塊。使用者可在 Looker 中指定篩選運算式,以設定臨時查詢。您也可以直接在 LookML 中宣告篩選運算式,套用至所有查詢。
Looker 查詢的基本元件
如上一個範例查詢所示,所有 Looker 查詢都是以套用至 LookML 專案的這些基本參數表示。
Looker 會使用下列參數產生完整的 SQL 查詢:
model
:要指定的 LookML 模型名稱,用於指定目標資料庫explore
:要查詢的探索名稱,會填入 SQLFROM
子句- 欄位:查詢中要加入的
dimension
和measure
參數,會填入 SQLSELECT
子句 filter
:要套用至零個或多個欄位的 Looker 篩選條件運算式,會填入 SQLWHERE
和HAVING
子句- 排序順序:用於排序的欄位和排序順序,會填入 SQL
ORDER BY
子句
這些參數正是使用者在 Looker「探索」頁面建立查詢時指定的元素。這些元素會出現在所有使用 Looker 執行查詢的模式中,例如產生的 SQL、代表查詢的網址,以及 Looker API。
LEFT JOIN
子句指定的檢視區塊呢?系統會根據 LookML 模型的結構填入 JOIN
子句,指定檢視區塊如何加入 Explore。建構 SQL 查詢時,Looker 只會在必要時加入 JOIN
子句。使用者在 Looker 中建立查詢時,不必指定資料表如何聯結,因為這項資訊已編碼至模型中,這是 Looker 為商務使用者帶來的強大優勢之一。
查詢範例和產生的 SQL
我們將在 Looker 中建構查詢,示範如何根據先前的模式產生查詢。假設電子商務商店的資料庫有「訂單」和「使用者」這兩個資料表,用於追蹤使用者和訂單。
orders |
---|
id INT |
created_at DATETIME |
users_id INT |
status VARCHAR(255) |
traffic_source VARCHAR(15) |
users |
---|
id INT |
email VARCHAR(255) |
first_name VARCHAR(255) |
last_name VARCHAR(255) |
created_at DATETIME |
zip INT |
country VARCHAR(255) |
state VARCHAR(255) |
city VARCHAR(255) |
age INT |
traffic_source VARCHAR(15) |
我們將在 Looker 探索中,依州別 (USERS State) 分組,並依訂單建立日期 (ORDERS Created Date) 篩選,找出訂單數量 (ORDERS Count)。
如要查看 Looker 產生及執行的 SQL 查詢,請按一下「資料」面板中的「SQL」分頁。
SELECT COALESCE(users.state, ' ') AS "_g1",
users.state AS 'users.state',
COUNT(DISTINCT orders.id) AS 'orders.count'
FROM orders
LEFT JOIN users ON orders.user_id = users.id
WHERE
orders.created_at BETWEEN (CONVERT_TZ(DATE_ADD(CURDATE(), INTERVAL -29 day), 'America/Los_Angeles', 'UTC',)) AND (CONVERT_TZ(DATE_ADD(DATE_ADD(DATE_ADD(CURDATE(), INTERVAL -29 day), INTERVAL 30 day), INTERVAL -1 second), 'America/Los_Angeles', 'UTC'))
GROUP BY 1
ORDER BY COUNT(DISTINCT orders.id) DESC
LIMIT 500
請注意,這與標準查詢公式類似。Looker SQL 具有一些機器生成的程式碼特徵 (例如 COALESCE(users.state,'') AS "_g1"
),但一律符合公式。
在 Looker 中進行更多查詢實驗,證明查詢結構一律相同。
在 Looker 的 SQL Runner 中執行原始 SQL
Looker 內建 SQL Runner 功能,可針對您在 Looker 中設定的資料庫連線,執行任何 SQL 查詢。
由於 Looker 產生的每項查詢都會產生完整且可執行的 SQL 指令,因此您可以使用 SQL Runner 檢查或執行查詢。
在 SQL Runner 中執行的原始 SQL 查詢會產生相同的結果集。如果 SQL 含有任何錯誤,SQL Runner 會在 SQL 指令中醒目顯示第一個錯誤的位置,並在錯誤訊息中指出錯誤位置。
檢查展開網址中的查詢元件
在 Looker 中執行查詢後,您可以檢查展開的網址,查看 Looker 查詢的基本元件。首先,請從「探索」的齒輪選單中選取「分享」,開啟「分享網址」選單。
擴展網址提供的資訊足以重現查詢。舉例來說,這個展開的網址範例提供下列資訊:
https://<Looker instance URL>.cloud.looker.com/explore/e_thelook/events?fields=users.state,users.count
&f[users.created_year]=2020&sorts=users.count+desc&limit=500
模型 | e_thelook |
探索 | events |
要查詢及顯示的欄位 | fields=users.state,users.count |
排序欄位和順序 | sorts=users.count+desc |
篩選欄位和值 | f[users.created_year]=2020 |
Looker 如何建構 JOIN
在上述查詢範例中,請注意「探索」orders
會顯示在主要 FROM
子句中,而彙整的檢視畫面則會顯示在 LEFT JOIN
子句中。撰寫 Looker 聯結的方式有很多種,詳情請參閱「在 LookML 中使用聯結」頁面。
SQL 區塊會指定自訂 SQL 子句
並非所有 Looker 查詢元素都是機器生成的。資料模型必須在某個時間點提供特定詳細資料,Looker 才能存取基礎資料表並計算衍生值。在 LookML 中,SQL 區塊是資料模型師提供的 SQL 程式碼片段,Looker 會使用這些片段合成完整的 SQL 運算式。
最常見的 SQL 區塊參數是 sql
,用於維度和指標定義。sql
參數會指定 SQL 子句,用於參照基礎資料欄或執行匯總函式。一般來說,所有以 sql_
開頭的 LookML 參數都會預期某種形式的 SQL 運算式。例如:sql_always_where
、sql_on
和 sql_table_name
。如要進一步瞭解各個參數,請參閱 LookML 參考資料。
維度和指標的 SQL 區塊範例
以下程式碼範例提供維度和指標的 SQL 區塊。LookML 替代運算子 ($) 會讓這些 sql
宣告看起來不像 SQL。不過,完成替代後,產生的字串就是純 SQL,Looker 會將其插入查詢的 SELECT
子句。
dimension: id {
primary_key: yes
sql: ${TABLE}.id ;; # Specify the primary key, id
}
measure: average_cost {
type: average
value_format: "0.00"
sql: ${cost} ;; # Specify the field that you want to average
# The field 'cost' is declared elsewhere
}
dimension: name {
sql: CONCAT(${first_name}, ' ', ${last_name}) ;;
}
dimension: days_in_inventory {
type: number
sql: DATEDIFF(${sold_date}, ${created_date}) ;;
}
如本例最後兩個維度所示,SQL 區塊可使用基礎資料庫支援的函式 (例如本例中的 MySQL 函式 CONCAT
和 DATEDIFF
)。SQL 區塊中使用的程式碼必須與資料庫使用的 SQL 方言相符。
衍生資料表的 SQL 區塊範例
衍生資料表也會使用 SQL 區塊指定衍生資料表的查詢。以下是以 SQL 為基礎的衍生資料表範例:
view: user_order_facts {
derived_table: {
sql:
SELECT
user_id
, COUNT(*) as lifetime_orders
FROM orders
GROUP BY 1 ;;
}
# later, dimension declarations reference the derived column(s)…
dimension: lifetime_orders {
type: number
}
}
用於篩選探索的 SQL 區塊範例
sql_always_where
和 sql_always_having
LookML 參數可將 SQL 區塊插入 SQL WHERE 或 HAVING 子句,藉此限制查詢可用的資料。在本例中,LookML 替代運算子 ${view_name.SQL_TABLE_NAME}
用於參照衍生資料表:
explore: trips {
view_label: "Long Trips"
# This will ensure that we only see trips that are longer than average!
sql_always_where: ${trips.trip_duration}>=(SELECT tripduration FROM ${average_trip_duration.SQL_TABLE_NAME});;
}