在工作階段中編寫查詢
本文件說明如何在 BigQuery 工作階段中編寫查詢。本文章適用於已對 BigQuery 工作階段有基本瞭解,並知道如何在工作階段中執行查詢的使用者。
工作階段會儲存狀態。在工作階段中建立的狀態會保留,並可在整個工作階段中使用。因此,如果您在一個查詢項目中建立臨時資料表,就可以在其他查詢項目中使用該臨時資料表,直到工作階段結束為止。
工作階段支援工作階段變數、工作階段系統變數、多陳述式查詢和多陳述式交易。
完成這些步驟前,請確認您具備在工作階段中執行作業所需的權限。
在工作階段中使用系統變數
您可以使用下列系統變數設定或擷取工作階段層級資料:
@@dataset_id
:目前專案中預設資料集的 ID。系統變數@@dataset_project_id
和@@dataset_id
可以一起設定及使用。@@dataset_project_id
:在查詢中使用的資料集預設專案 ID。如果未設定這個系統變數,或是將其設為NULL
,系統會使用執行查詢的專案。系統變數@@dataset_project_id
和@@dataset_id
可以一起設定及使用。@@query_label
:要指派給工作階段的工作標籤。標籤可用於整個工作階段,而非僅用於工作階段中的特定查詢。@@session_id
:目前工作階段的 ID。@@time_zone
:在時區相關 SQL 函式中,如未指定時區做為引數,就會使用這個預設時區。
這些系統變數可在工作階段的任何時間使用,且在後續工作階段的範圍內。您不需要定義這些變數,但可以使用 SET
陳述式為這些變數指派新值。
在工作階段中,變數的大小上限為 1 MB,而工作階段中所有變數的總和上限為 10 MB。
為工作階段指派標籤
您可以為工作階段指派工作標籤。這樣一來,日後工作階段中的所有查詢都會指派給標籤。標籤可在工作階段的任何時間點使用,且在工作階段的剩餘時間內都有效。您指派的工作標籤會顯示在稽核記錄中。
在工作階段中使用變數
您可以使用變數建立、設定及擷取工作階段層級資料。變數可在工作階段的任何時間點使用,且在後續工作階段內有效。
- 如要建立會話範圍變數,請在
BEGIN...END
區塊外使用DECLARE
陳述式。 - 如要在建立後設定會話範圍變數,請使用
SET
陳述式。 - 在
BEGIN...END
區塊中宣告的變數並非工作階段範圍變數。 - 您可以在
BEGIN...END
區塊中參照工作階段範圍變數。 - 您可以在
BEGIN...END
區塊中設定工作階段範圍變數。
在工作階段中,變數的大小上限為 1 MB,而工作階段中所有變數的總和上限為 10 MB。
在工作階段中使用臨時資料表
您可以使用暫時性資料表,將中繼結果儲存至資料表。臨時資料表會顯示在工作階段層級,因此您不需要在資料集中儲存或維護臨時資料表。工作階段結束後,系統會自動刪除該檔案。在工作階段處於活動狀態時,您必須為臨時資料表的儲存空間付費。如要進一步瞭解臨時表,請參閱「使用多個陳述式的查詢」一文。
在工作階段中使用暫時性函式
暫時函式會顯示在工作階段層級,因此您不需要在資料集中儲存或維護該函式。工作階段結束後,系統會自動刪除。
在工作階段中使用多個陳述式的查詢
您可以在工作階段中使用 GoogleSQL 多陳述式查詢。指令碼可為每個指令碼加入臨時資料表和系統變數。工作階段變數和臨時資料表會顯示在指令碼中。在指令碼中宣告的所有頂層變數也是工作階段變數。
在工作階段中執行多項查詢和多陳述式交易
您可以在單一工作階段中,針對多個查詢執行多陳述式交易。例如:
下列查詢會開始交易。
BEGIN TRANSACTION
在交易中,下列查詢會建立名為 Flights
的臨時資料表,然後傳回這個資料表中的資料。查詢中包含兩個陳述式。
CREATE TEMP TABLE Flights(total INT64) AS SELECT * FROM UNNEST([10,23,3,14,55]) AS a;
SELECT * FROM Flights;
以下查詢會提交交易。
COMMIT
您可以找出影響 Flights
資料表的有效交易:
WITH running_transactions AS (
SELECT DISTINCT transaction_id
FROM
`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
EXCEPT DISTINCT
SELECT transaction_id FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE
creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
AND statement_type = "COMMIT_TRANSACTION"
OR statement_type = "ROLLBACK_TRANSACTION"
)
SELECT
jobs.transaction_id AS transaction_id,
project_id,
user_email,
session_info.session_id,
query
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT AS jobs, running_transactions
WHERE
creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
AND destination_table = ("Flights")
AND jobs.transaction_id = running_transactions.transaction_id;
如果您想取消進行中的交易,且擁有 bigquery.admin
角色,可以使用與 Cloud Shell 或 API 呼叫中的交易相關聯的會話 ID,發出回溯語句。當您使用與交易相關聯的工作階段 ID 執行查詢時,結果中就會顯示工作階段 ID。
工作階段範例
以下是 Google Cloud 主控台中工作階段工作流程的範例:
在 Google Cloud 控制台中開啟新的編輯器分頁,然後建立工作階段。
在編輯器分頁中,新增下列查詢:
CREATE TEMP TABLE Flights(total INT64) AS SELECT * FROM UNNEST([10,23,3,14,55]) AS a; SELECT * FROM Flights;
執行查詢。系統會建立名為
Flights
的臨時資料表,並傳回所有資料。+-------+ | total | +-------+ | 55 | | 23 | | 3 | | 14 | | 10 | +-------+
刪除編輯器分頁中的內容,然後新增下列查詢:
SELECT * FROM Flights LIMIT 2;
執行查詢。系統會傳回兩筆記錄的結果。即使您刪除了先前的查詢,查詢所提供的資訊仍會儲存在目前的工作階段中。
+-------+ | total | +-------+ | 55 | | 23 | +-------+
刪除編輯器分頁中的內容,然後新增下列查詢:
DECLARE x INT64 DEFAULT 10; SELECT total * x AS total_a FROM Flights LIMIT 2; BEGIN SET x = 100; SELECT total * x AS total_b FROM Flights LIMIT 2; END; SELECT total * x AS total_c FROM Flights LIMIT 2;
執行查詢。會話範圍變數
x
可用來限制Flights
資料表傳回的結果數量。請仔細觀察,當這個變數在BEGIN...END
陳述式外宣告、在BEGIN...END
陳述式內設定,然後在BEGIN...END
陳述式外再次參照時,範圍會如何影響這個變數。+---------+ | total_a | +---------+ | 550 | | 230 | +---------+ +---------+ | total_b | +---------+ | 5500 | | 2300 | +---------+ +---------+ | total_c | +---------+ | 5500 | | 2300 | +---------+
刪除編輯器分頁中的內容,然後新增下列查詢:
SELECT STRING(TIMESTAMP "2008-12-20 15:30:00+00", @@time_zone) AS default_time_zone; SET @@time_zone = "America/Los_Angeles"; SELECT STRING(TIMESTAMP "2008-12-20 15:30:00+00", @@time_zone) AS new_time_zone;
執行查詢。會話範圍系統變數
@@time_zone
用於將時區指派給時間戳記。第一個陳述式會傳回含有預設時區 (在本例中為UTC
) 的時間戳記。下一個陳述式會將@@time_zone
指派給新值。第三個陳述式會傳回含有新時區的時間戳記。+-------------------------------+ | default_time_zone | +-------------------------------+ | 2008-12-20 15:30:00+00 | +-------------------------------+ +-------------------------------+ | new_time_zone | +-------------------------------+ | 2008-12-20 07:30:00-08 | +-------------------------------+