Teradata SQL 翻譯指南
本文詳述 SQL 語法中 Teradata 和 BigQuery 之間的相似與差異之處,協助您規劃遷移作業。使用批次 SQL 翻譯功能大量遷移 SQL 指令碼,或使用互動式 SQL 翻譯功能翻譯臨時查詢。
資料類型
本節說明 Teradata 和 BigQuery 的資料類型對應關係。
Teradata | BigQuery | 附註 |
---|---|---|
INTEGER | INT64 | |
SMALLINT | INT64 | |
BYTEINT | INT64 | |
BIGINT | INT64 | |
DECIMAL | 如果精度 (小數點後的位數) 小於或等於 9,請使用 BigQuery 的 如果您需要強制執行自訂位數或比例邊界 (限制),請使用 BigQuery 的參數化小數資料類型。 Teradata 可讓您透過捨入儲存值來插入精確度較高的值,但會在計算中保留高精確度。這可能會導致與 ANSI 標準相比,產生 非預期的捨入行為。 | |
FLOAT | FLOAT64 | |
NUMERIC | 如果精度 (小數點後的位數) 小於或等於 9,請使用 BigQuery 的 如果您需要強制執行自訂位數或比例邊界 (限制),請使用 BigQuery 的參數化小數資料類型。 Teradata 可讓您透過捨入儲存值來插入精確度較高的值,但會在計算中保留高精確度。這可能會導致與 ANSI 標準相比,產生 非預期的捨入行為。 | |
NUMBER | 如果精度 (小數點後的位數) 小於或等於 9,請使用 BigQuery 的 如果您需要強制執行自訂位數或比例邊界 (限制),請使用 BigQuery 的參數化小數資料類型。 Teradata 可讓您透過捨入儲存值來插入精確度較高的值,但會在計算中保留高精確度。這可能會導致與 ANSI 標準相比,產生 非預期的捨入行為。 | |
REAL | FLOAT64 | |
CHAR/CHARACTER | STRING | 如果您需要強制設定字元長度上限,請使用 BigQuery 的 參數化 |
VARCHAR | STRING | 如果您需要強制設定字元長度上限,請使用 BigQuery 的 參數化 |
CLOB | STRING | |
JSON | JSON | |
BLOB | BYTES | |
BYTE | BYTES | |
VARBYTE | BYTES | |
DATE | DATE | BigQuery 不支援 SDF 中 Teradata 支援的自訂格式。 |
TIME | TIME | |
TIME WITH TIME ZONE | TIME | Teradata 會以 UTC 格式儲存 TIME 資料類型,並允許您使用 WITH TIME ZONE 語法傳遞 UTC 時差。 BigQuery 中的 TIME 資料類型代表不受任何日期或時區影響的時間。 |
TIMESTAMP | TIMESTAMP | Teradata 和 BigQuery 的 TIMESTAMP 資料類型都具有微秒精確度 (但 Teradata 支援閏秒,而 BigQuery 不支援)。Teradata 和 BigQuery 資料類型通常都會與 UTC 時區相關聯 (詳情)。 |
TIMESTAMP WITH TIME ZONE | TIMESTAMP | Teradata TIMESTAMP 可設定為系統層級、每個使用者或每個資料欄的不同時區 (使用 WITH TIME ZONE )。如果您未明確指定時區,BigQuery TIMESTAMP 類型會假設為世界標準時間。請務必正確匯出時區資訊 (不要在沒有時區資訊的情況下連結 DATE 和 TIME 值),以便 BigQuery 在匯入時進行轉換。或者,請務必在匯出前將時區資訊轉換為世界標準時間。BigQuery 提供 DATETIME ,用於將公元時間與 TIMESTAMP 之間的差異抽象化,前者在輸出時不會顯示時區,後者則是精確的時間點,一律會顯示世界標準時間。 |
ARRAY | ARRAY | |
MULTI-DIMENSIONAL ARRAY | ARRAY | 在 BigQuery 中,請使用結構體陣列,其中每個結構體都包含 ARRAY 類型的欄位 (詳情請參閱 BigQuery 說明文件)。 |
INTERVAL HOUR | INT64 | |
INTERVAL MINUTE | INT64 | |
INTERVAL SECOND | INT64 | |
INTERVAL DAY | INT64 | |
INTERVAL MONTH | INT64 | |
INTERVAL YEAR | INT64 | |
PERIOD(DATE) | DATE ,DATE | PERIOD(DATE) 應轉換為包含開始日期和結束日期的兩個 DATE 資料欄,以便與時間窗口函式搭配使用。 |
PERIOD(TIMESTAMP WITH TIME ZONE) | TIMESTAMP ,TIMESTAMP | |
PERIOD(TIMESTAMP) | TIMESTAMP ,TIMESTAMP | |
PERIOD(TIME) | TIME ,TIME | |
PERIOD(TIME WITH TIME ZONE) | TIME ,TIME | |
UDT | STRING | |
XML | STRING | |
TD_ANYTYPE | STRING |
如要進一步瞭解型別轉換,請參閱下一節。
Teradata 類型格式設定
Teradata SQL 會使用一組預設格式,用於顯示運算式和資料欄資料,以及在資料類型之間進行轉換。例如,INTEGERDATE
模式中的 PERIOD(DATE)
資料類型預設格式為 YY/MM/DD
。建議您盡可能使用 ANSIDATE 模式,確保符合 ANSI SQL 規範,並利用這個機會清理舊版格式。
Teradata 可讓您使用 FORMAT
子句自動套用自訂格式,而無須變更基礎儲存空間,無論是使用 DDL 建立資料表時,或是在衍生運算式中,都可以將其做為資料類型屬性。例如,FORMAT
規格 9.99
會將任何 FLOAT
值四捨五入至兩位數。在 BigQuery 中,必須使用 ROUND()
函式才能轉換這項功能。
這項功能需要處理複雜的極端情況。舉例來說,當 FORMAT
子句套用至 NUMERIC
欄時,您必須考量特殊捨入和格式規則。您可以使用 FORMAT
子句,將 INTEGER
紀元值隱含轉換為 DATE
格式。或者,VARCHAR
欄上的 FORMAT
規格 X(6)
會截斷資料欄值,因此您必須轉換為 SUBSTR()
函式。這項行為不符合 ANSI SQL 規範。因此,我們建議您不要將資料欄格式遷移至 BigQuery。
如果必須使用資料欄格式,請使用檢視畫面或使用者定義函式 (UDF)。
如要瞭解 Teradata SQL 為每種資料類型使用的預設格式,請參閱 Teradata 預設格式說明文件。
時間戳記和日期類型格式
下表概略說明 Teradata SQL 和 GoogleSQL 之間的時間戳記和日期格式化元素差異。
Teradata 格式 | Teradata 說明 | BigQuery |
---|---|---|
CURRENT_TIMESTAMP | Teradata 中的 TIME 和 TIMESTAMP 資訊可能會有不同的時區資訊,這些資訊會使用 WITH TIME ZONE 定義。 | 盡可能使用採用 ISO 格式的 CURRENT_TIMESTAMP() 。不過,輸出格式一律會顯示世界標準時間時區。(BigQuery 內部並未設定時區)。請注意下列 ISO 格式差異的詳細說明。 DATETIME 會根據輸出管道慣例進行格式設定。在 BigQuery 指令列工具和 BigQuery 主控台中,這項資訊會根據 RFC 3339 使用 T 分隔符進行格式設定。不過,在 Python 和 Java JDBC 中,空格會用來做為分隔符。如果您想使用明確的格式,請使用 FORMAT_DATETIME() ,這樣就能明確將值轉換為字串。例如,下列運算式一律會傳回空格分隔符:CAST(CURRENT_DATETIME() AS STRING) Teradata 支援 TIME 資料欄中的 DEFAULT 關鍵字,用於設定目前時間 (時間戳記);這項功能不會在 BigQuery 中使用。 |
CURRENT_DATE | 日期會以 INT64 值的形式儲存在 Teradata 中,並使用以下公式:(YEAR - 1900) * 10000 + (MONTH * 100) + DAY 日期可設為整數格式。 | BigQuery 有個獨立的 DATE 格式,一律會以 ISO 8601 格式傳回日期。DATE_FROM_UNIX_DATE 無法使用,因為它是以 1970 年為基準。Teradata 支援在 DATE 資料欄中使用 DEFAULT 關鍵字來設定目前日期,但這並未在 BigQuery 中使用。 |
CURRENT_DATE-3 | 日期值會以整數表示。Teradata 支援日期類型的算術運算子。 | 如為日期類型,請使用 DATE_ADD() 或 DATE_SUB() 。BigQuery 會使用算術運算子處理資料類型: INT64 、NUMERIC 和 FLOAT64 。 |
SYS_CALENDAR.CALENDAR | Teradata 提供日曆運算檢視畫面,可用於執行整數運算以外的作業。 | 在 BigQuery 中不使用。 |
SET SESSION DATEFORM=ANSIDATE | 將工作階段或系統日期格式設為 ANSI (ISO 8601)。 | BigQuery 一律使用 ISO 8601,因此請務必轉換 Teradata 日期和時間。 |
查詢語法
本節將說明 Teradata 和 BigQuery 之間的查詢語法差異。
SELECT
陳述式
大部分的 Teradata SELECT
陳述式都與 BigQuery 相容。下表列出一些細微差異。
Teradata | BigQuery | |
---|---|---|
SEL | 轉換為 SELECT 。BigQuery 不會使用 SEL 縮寫。 | |
SELECT | 在 BigQuery 中,資料欄無法參照同一個選取清單中定義的其他資料欄輸出內容。建議將子查詢移至 WITH 子句。WITH flags AS ( | |
SELECT * FROM table | BigQuery 不會使用 ANY 邏輯述詞。您可以使用多個 OR 運算子來達成相同的功能:SELECT * FROM table 在這種情況下,字串比較也會有所不同。請參閱「比較運算子」。 | |
SELECT TOP 10 * FROM table | BigQuery 會在查詢結尾使用 LIMIT ,而非在 SELECT 關鍵字後使用 TOP n 。 |
比較運算子
下表列出 Teradata 專用的 Teradata 比較運算子,必須轉換為 BigQuery 使用的 ANSI SQL:2011 相容運算子。
如要瞭解 BigQuery 中的運算子,請參閱 BigQuery 說明文件中的「運算子」一節。
Teradata | BigQuery | 附註 |
---|---|---|
exp EQ exp2 exp IN (exp2, exp3) | exp = exp2 exp IN (exp2, exp3) 如要保留 NOT CASESPECIFIC 的非 ANSI 語意,您可以使用RTRIM(UPPER(exp)) = RTRIM(UPPER(exp2)) | 比較字串是否相等時,Teradata「可能」會忽略結尾空白,而 BigQuery 會將空白視為字串的一部分。舉例來說,'xyz'=' xyz' 在 Teradata 中為 TRUE ,但在 BigQuery 中為 FALSE 。Teradata 也提供 NOT CASESPECIFIC 資料欄屬性,可指示 Teradata 在比較兩個字串時忽略大小寫。比較字串時,BigQuery 一律會區分大小寫。舉例來說,'xYz' = 'xyz' 在 Teradata 中為 TRUE ,但在 BigQuery 中為 FALSE 。 |
exp LE exp2 | exp <= exp2 | |
exp LT exp2 | exp < exp2 | |
exp NE exp2 | exp <> exp2 | |
exp GE exp2 | exp >= exp2 | |
exp GT exp2 | exp > exp2 |
JOIN
個條件
BigQuery 和 Teradata 支援相同的 JOIN
、ON
和 USING
條件。下表列出一些細微差異。
Teradata | BigQuery | 附註 |
---|---|---|
FROM A JOIN B ON A.date > B.start_date AND A.date < B.end_date | FROM A LEFT OUTER JOIN B ON A.date > B.start_date AND A.date < B.end_date | BigQuery 支援不等式 JOIN 子句,適用於所有內聯結或至少提供一個相等條件 (=)。但 OUTER JOIN 中不只支援一個不等式條件 (= 和 <)。這類結構有時會用於查詢日期或整數範圍。BigQuery 可防止使用者不小心建立大型交叉彙整。 |
FROM A, B ON A.id = B.id | FROM A JOIN B ON A.id = B.id | 在 Teradata 中,資料表之間使用半形逗號等同於 INNER JOIN ,而在 BigQuery 中則等同於 CROSS JOIN (笛卡兒積)。由於 BigQuery 舊版 SQL 中的逗號會視為 UNION ,因此建議您明確指定運算,以免造成混淆。 |
FROM A JOIN B ON (COALESCE(A.id , 0) = COALESCE(B.id, 0)) | FROM A JOIN B ON (COALESCE(A.id , 0) = COALESCE(B.id, 0)) | 純量 (常數) 函式則沒有差異。 |
FROM A JOIN B ON A.id = (SELECT MAX(B.id) FROM B) | FROM A JOIN (SELECT MAX(B.id) FROM B) B1 ON A.id = B1.id | BigQuery 會禁止使用者在彙整述詞中使用子查詢、關聯子查詢或匯總。這樣一來,BigQuery 就能並行執行查詢。 |
類型轉換和轉換
BigQuery 的資料類型比 Teradata 少,但範圍更廣,因此 BigQuery 在轉換時必須更加嚴格。
Teradata | BigQuery | 附註 |
---|---|---|
exp EQ exp2 exp IN (exp2, exp3) | exp = exp2 exp IN (exp2, exp3) 如要保留 NOT CASESPECIFIC 的非 ANSI 語意,您可以使用RTRIM(UPPER(exp)) = RTRIM(UPPER(exp2)) | 比較字串是否相等時,Teradata「可能」會忽略結尾空白,而 BigQuery 會將空白視為字串的一部分。舉例來說,'xyz'=' xyz' 在 Teradata 中為 TRUE ,但在 BigQuery 中為 FALSE 。Teradata 也提供 NOT CASESPECIFIC 資料欄屬性,可指示 Teradata 在比較兩個字串時忽略大小寫。比較字串時,BigQuery 一律會區分大小寫。舉例來說,'xYz' = 'xyz' 在 Teradata 中為 TRUE ,但在 BigQuery 中為 FALSE 。 |
CAST(long_varchar_column AS CHAR(6)) | LPAD(long_varchar_column, 6) | 在 Teradata 中轉換字元欄時,有時會用來建立填入的子字串,但這並非標準做法,也不是最佳做法。 |
CAST(92617 AS TIME) 92617 (FORMAT '99:99:99') | PARSE_TIME("%k%M%S", CAST(92617 AS STRING)) | 相較於 BigQuery,Teradata 會執行更多隱含類型轉換和捨入作業,且通常會更嚴格地強制執行 ANSI 標準。 (這個範例會傳回 09:26:17) |
CAST(48.5 (FORMAT 'zz') AS FLOAT) | CAST(SUBSTR(CAST(48.5 AS STRING), 0, 2) AS FLOAT64) | 浮點和數值資料類型在套用貨幣等格式時,可能需要特殊的捨入規則。 (這個範例會傳回 48) |
將 FLOAT
/DECIMAL
投放到 INT
如果 Teradata 使用高斯和銀行家演算法將數字四捨五入,請在 BigQuery 中使用 ROUND_HALF_EVEN
RoundingMode
:
round(CAST(2.5 as Numeric),0, 'ROUND_HALF_EVEN')
將 STRING
投放到 NUMERIC
或 BIGNUMERIC
從 STRING
轉換為數值時,請根據 STRING
值的小數點數使用正確的資料類型,也就是 NUMERIC
或 BIGNUMERIC
。
如要進一步瞭解 BigQuery 支援的數字精確度和小數位數,請參閱「十進制類型」。
另請參閱比較運算子和欄格式。比較和資料欄格式化都會像型別轉換一樣運作。
QUALIFY
、ROWS
子句
Teradata 中的 QUALIFY
子句可讓您篩選窗型函式的結果。或者,您也可以使用 ROWS
片語來執行相同的任務。這些運算方式與 GROUP
子句的 HAVING
條件類似,可限制 BigQuery 中稱為時間窗口函式的輸出內容。
Teradata | BigQuery |
---|---|
SELECT col1, col2 | 在 BigQuery 中,含有 ROW_NUMBER() 、SUM() 、COUNT() 等時間窗口函式和 OVER PARTITION BY 的 Teradata QUALIFY 子句會以包含分析值的子查詢中的 WHERE 子句表示。使用 ROW_NUMBER() :SELECT col1, col2 使用支援較大分割區的 ARRAY_AGG :SELECT |
SELECT col1, col2 | SELECT col1, col2 在 BigQuery 中, RANGE 和 ROWS 都可以用於窗格框架子句。不過,窗型子句只能搭配 AVG() 等窗型函式使用,不能搭配 ROW_NUMBER() 等編號函式使用。 |
SELECT col1, col2 | SELECT col1, |
NORMALIZE
關鍵字
Teradata 為 SELECT
子句提供 NORMALIZE
關鍵字,可將重疊的期間或間隔合併為單一期間或間隔,涵蓋所有個別期間值。
BigQuery 不支援 PERIOD
類型,因此 Teradata 中的任何 PERIOD
類型欄必須以兩個個別的 DATE
或 DATETIME
欄位插入 BigQuery,這些欄位對應於期間的開始和結束時間。
Teradata | BigQuery |
---|---|
SELECT NORMALIZE | SELECT |
函式
下列各節列出 Teradata 函式與 BigQuery 對應項目。
匯總函式
下表將常見的 Teradata 匯總、統計匯總和概略匯總函式,對應至 BigQuery 的等同函式。BigQuery 提供下列其他匯總函式:
ANY_VALUE
APPROX_COUNT_DISTINCT
APPROX_QUANTILES
APPROX_TOP_COUNT
APPROX_TOP_SUM
COUNTIF
LOGICAL_AND
LOGICAL_OR
STRING_AGG
Teradata | BigQuery |
---|---|
AVG | AVG 注意:BigQuery 會在計算 INT 值的平均值時提供近似結果。 |
BITAND | BIT_AND |
BITNOT | 位元運算「not」運算子 (~ ) |
BITOR | BIT_OR |
BITXOR | BIT_XOR |
CORR | CORR |
COUNT | COUNT |
COVAR_POP | COVAR_POP |
COVAR_SAMP | COVAR_SAMP |
MAX | MAX |
MIN | MIN |
REGR_AVGX | AVG( |
REGR_AVGY | AVG( |
REGR_COUNT | SUM( |
REGR_INTERCEPT | AVG(dep_var_expression) - AVG(ind_var_expression) * (COVAR_SAMP(ind_var_expression, |
REGR_R2 | (COUNT(dep_var_expression)* |
REGR_SLOPE | - COVAR_SAMP(ind_var_expression, |
REGR_SXX | SUM(POWER(ind_var_expression, 2)) - COUNT(ind_var_expression) * |
REGR_SXY | SUM(ind_var_expression * dep_var_expression) - COUNT(ind_var_expression) |
REGR_SYY | SUM(POWER(dep_var_expression, 2)) - COUNT(dep_var_expression) |
SKEW | 自訂使用者定義函式。 |
STDDEV_POP | STDDEV_POP |
STDDEV_SAMP | STDDEV_SAMP, STDDEV |
SUM | SUM |
VAR_POP | VAR_POP |
VAR_SAMP | VAR_SAMP, VARIANCE |
分析函式和窗型函式
下表列出常見的 Teradata 分析函式和匯總分析函式,以及對應的 BigQuery 視窗函式。BigQuery 提供下列其他函式:
日期/時間函式
下表列出常見的 Teradata 日期/時間函式與 BigQuery 對應函式的對應關係。BigQuery 提供下列其他日期/時間函式:
CURRENT_DATETIME
DATE_ADD
DATE_DIFF
DATE_FROM_UNIX_DATE
DATE_SUB
DATE_TRUNC
DATETIME
DATETIME_ADD
DATETIME_DIFF
DATETIME_SUB
DATETIME_TRUNC
PARSE_DATE
PARSE_DATETIME
PARSE_TIME
PARSE_TIMESTAMP
STRING
TIME
TIME_ADD
TIME_DIFF
TIME_SUB
TIME_TRUNC
TIMESTAMP
TIMESTAMP_ADD
TIMESTAMP_DIFF
TIMESTAMP_MICROS
TIMESTAMP_MILLIS
TIMESTAMP_SECONDS
TIMESTAMP_SUB
TIMESTAMP_TRUNC
UNIX_DATE
UNIX_MICROS
UNIX_MILLIS
UNIX_SECONDS
Teradata | BigQuery |
---|---|
ADD_MONTHS | DATE_ADD, TIMESTAMP_ADD |
CURRENT_DATE | CURRENT_DATE |
CURRENT_TIME | CURRENT_TIME |
CURRENT_TIMESTAMP | CURRENT_TIMESTAMP |
DATE + k | DATE_ADD(date_expression, INTERVAL k DAY) |
DATE - k | DATE_SUB(date_expression, INTERVAL k DAY) |
EXTRACT | EXTRACT(DATE), EXTRACT(TIMESTAMP) |
FORMAT_DATE | |
FORMAT_DATETIME | |
FORMAT_TIME | |
FORMAT_TIMESTAMP | |
LAST_DAY | LAST_DAY 注意:此函式支援 DATE 和 DATETIME 輸入運算式。 |
MONTHS_BETWEEN | DATE_DIFF(date_expression, date_expression, MONTH) |
NEXT_DAY | DATE_ADD( |
OADD_MONTHS | DATE_SUB( |
td_day_of_month | EXTRACT(DAY FROM date_expression) |
td_day_of_week | EXTRACT(DAYOFWEEK FROM date_expression) |
td_day_of_year | EXTRACT(DAYOFYEAR FROM date_expression) |
td_friday | DATE_TRUNC( |
td_monday | DATE_TRUNC( |
td_month_begin | DATE_TRUNC(date_expression, MONTH) |
td_month_end | DATE_SUB( |
td_month_of_calendar | (EXTRACT(YEAR FROM date_expression) - 1900) * 12 + EXTRACT(MONTH FROM date_expression) |
td_month_of_quarter | EXTRACT(MONTH FROM date_expression) |
td_month_of_year | EXTRACT(MONTH FROM date_expression) |
td_quarter_begin | DATE_TRUNC(date_expression, QUARTER) |
td_quarter_end | DATE_SUB( |
td_quarter_of_calendar | (EXTRACT(YEAR FROM date_expression) |
td_quarter_of_year | EXTRACT(QUARTER FROM date_expression) |
td_saturday | DATE_TRUNC( |
td_sunday | DATE_TRUNC( |
td_thursday | DATE_TRUNC( |
td_tuesday | DATE_TRUNC( |
td_wednesday | DATE_TRUNC( |
td_week_begin | DATE_TRUNC(date_expression, WEEK) |
td_week_end | DATE_SUB( |
td_week_of_calendar | (EXTRACT(YEAR FROM date_expression) - 1900) * 52 + EXTRACT(WEEK FROM date_expression) |
td_week_of_month | EXTRACT(WEEK FROM date_expression) |
td_week_of_year | EXTRACT(WEEK FROM date_expression) |
td_weekday_of_month | CAST( |
td_year_begin | DATE_TRUNC(date_expression, YEAR) |
td_year_end | DATE_SUB( |
td_year_of_calendar | EXTRACT(YEAR FROM date_expression) |
TO_DATE | PARSE_DATE |
TO_TIMESTAMP | PARSE_TIMESTAMP |
TO_TIMESTAMP_TZ | PARSE_TIMESTAMP |
字串函式
下表列出 Teradata 字串函式與 BigQuery 相應函式的對應關係。BigQuery 提供下列其他字串函式:
BYTE_LENGTH
CODE_POINTS_TO_BYTES
ENDS_WITH
FROM_BASE32
FROM_BASE64
FROM_HEX
NORMALIZE
NORMALIZE_AND_CASEFOLD
REGEXP_CONTAINS
REGEXP_EXTRACT
REGEXP_EXTRACT_ALL
REPEAT
REPLACE
SAFE_CONVERT_BYTES_TO_STRING
SPLIT
STARTS_WITH
STRPOS
TO_BASE32
TO_BASE64
TO_CODE_POINTS
TO_HEX
數學函式
下表列出 Teradata 數學函式與 BigQuery 對應的函式。BigQuery 提供下列其他數學函式:
Teradata | BigQuery |
---|---|
ABS | ABS |
ACOS | ACOS |
ACOSH | ACOSH |
ASIN | ASIN |
ASINH | ASINH |
ATAN | ATAN |
ATAN2 | ATAN2 |
ATANH | ATANH |
CEILING | CEIL |
CEILING | CEILING |
COS | COS |
COSH | COSH |
EXP | EXP |
FLOOR | FLOOR |
GREATEST | GREATEST |
LEAST | LEAST |
LN | LN |
LOG | LOG |
MOD (% 運算子) | MOD |
NULLIFZERO | NULLIF(expression, 0) |
POWER (** 運算子) | POWER, POW |
RANDOM | RAND |
ROUND | ROUND |
SIGN | SIGN |
SIN | SIN |
SINH | SINH |
SQRT | SQRT |
TAN | TAN |
TANH | TANH |
TRUNC | TRUNC |
ZEROIFNULL | IFNULL(expression, 0), COALESCE(expression, 0) |
Rounding 函式
如果 Teradata 使用高斯和 Banker 演算法將數字四捨五入,請在 BigQuery 中使用 ROUND_HALF_EVEN
RoundingMode
:
-- Teradata syntax
round(3.45,1)
-- BigQuery syntax
round(CAST(3.45 as Numeric),1, 'ROUND_HALF_EVEN')
DML 語法
本節說明 Teradata 和 BigQuery 之間的資料管理語言語法差異。
INSERT
陳述式
大部分的 Teradata INSERT
陳述式都與 BigQuery 相容。下表列出例外狀況。
BigQuery 中的 DML 指令碼與 Teradata 中的等效陳述式,在一致性意義上略有不同。如要瞭解快照隔離和工作階段與交易處理的概略說明,請參閱本文其他部分的 CREATE INDEX
一節。
Teradata | BigQuery |
---|---|
INSERT INTO table VALUES (...); | INSERT INTO table (...) VALUES (...); Teradata 提供 DEFAULT 關鍵字,用於非空值資料欄。注意:在 BigQuery 中,只有在目標資料表中所有資料欄的值依序號遞增排序時,才能在 INSERT 陳述式中省略資料欄名稱。 |
INSERT INTO table VALUES (1,2,3); | INSERT INTO table VALUES (1,2,3), Teradata 有多語句要求 (MSR) 的概念,可一次傳送多個 INSERT 陳述式。在 BigQuery 中,由於陳述式之間有隱含的交易邊界,因此不建議這麼做。請改用 多值 INSERT 。BigQuery 允許並行 INSERT 陳述式,但可能會排入佇列 UPDATE 。如要改善效能,請考慮採用下列做法: |
UPDATE
陳述式
大部分的 Teradata UPDATE
陳述式都與 BigQuery 相容,但以下項目除外:
- 使用
FROM
子句時,FROM
和SET
子句的順序會在 Teradata 和 BigQuery 中反轉。 - 在 GoogleSQL 中,每個
UPDATE
陳述式都必須包含WHERE
關鍵字,後接條件。如要更新資料表中的所有資料列,請使用WHERE true
。
最佳做法是將多個 DML 變異組合在一起,而非單一 UPDATE
和 INSERT
陳述式。BigQuery 中的 DML 指令碼與 Teradata 中的等效陳述式,在一致性語意上略有不同。如需快照隔離和工作階段與交易處理的總覽,請參閱本文其他部分的 CREATE INDEX
一節。
下表列出可完成相同工作的 Teradata UPDATE
陳述式和 BigQuery 陳述式。
如要進一步瞭解 BigQuery 中的 UPDATE
,請參閱 DML 說明文件中的 BigQuery UPDATE
範例。
Teradata | BigQuery | |
---|---|---|
UPDATE table_A | UPDATE table_A | |
UPDATE table alias | UPDATE table | |
UPDATE table_A | UPDATE table_A |
DELETE
和 TRUNCATE
陳述式
DELETE
和 TRUNCATE
陳述式都支援從資料表中移除資料列,且不會影響資料表結構定義或索引。TRUNCATE
會刪除所有資料,而 DELETE
則會從資料表中移除所選資料列。
在 BigQuery 中,DELETE
陳述式必須包含 WHERE
子句。如要刪除資料表中的所有資料列 (截斷),請使用 WHERE true
。為了加快對非常大型資料表的截斷作業,建議您使用 CREATE OR REPLACE TABLE ... AS SELECT
陳述式,在同一個資料表中使用 LIMIT 0
來取代自身。不過,請務必在使用時手動新增分區和分群資訊。
Teradata 會稍後清除已刪除的資料列。也就是說,DELETE
作業一開始的速度比 BigQuery 快,但之後就需要資源,尤其是影響資料表大部分內容的大規模 DELETE
作業。如要在 BigQuery 中使用類似的方法,建議您減少 DELETE
作業的數量,例如將不刪除的資料列複製到新資料表中。或者,您也可以移除整個分割區。這兩種做法都比原子 DML 變異更快。
如要進一步瞭解 BigQuery 中的 DELETE
,請參閱 DML 說明文件中的 DELETE
範例。
Teradata | BigQuery |
---|---|
BEGIN TRANSACTION; | 將表格內容替換為查詢輸出內容,就等同於交易。您可以使用查詢或複製作業來執行這項操作。 使用查詢作業: bq query --replace --destination_table table_A 'SELECT * FROM table_B'; 使用複製作業: bq cp -f table_A table_B |
DELETE database.table ALL; | DELETE FROM table WHERE TRUE; 或者,如果是超大型表格,可以使用更快速的方法: CREATE OR REPLACE table AS SELECT * FROM table LIMIT 0; |
MERGE
陳述式
MERGE
陳述式可以將 INSERT
、UPDATE
和 DELETE
作業合併成單一「upsert」陳述式,並以不可分割的形式執行這些作業。MERGE
作業必須與每個目標資料列的最多一個來源資料列相符。BigQuery 和 Teradata 都遵循 ANSI 語法。
Teradata 的 MERGE
作業僅限於在一個 存取模組處理器 (AMP) 中比對主索引鍵。相較之下,BigQuery 對於 MERGE
作業沒有大小或資料欄限制,因此使用 MERGE
是實用的最佳化方式。不過,如果 MERGE
主要是大量刪除作業,請參閱本文其他部分的 DELETE
最佳化方式。
BigQuery 中的 DML 指令碼與 Teradata 中的等效陳述式,在一致性語意上略有不同。舉例來說,在工作階段模式中,Teradata 的 SET 資料表可能會在 MERGE
作業期間忽略重複項目。如要瞭解如何處理 MULTISET 和 SET 資料表、快照隔離作業、工作階段和交易處理作業,請參閱本文其他部分的 CREATE INDEX
一節。
受資料列影響的變數
在 Teradata 中,ACTIVITY_COUNT
變數是 Teradata ANSI SQL 擴充功能,其中填入了 DML 陳述式所影響的資料列數量。
指令碼功能中的 @@row_count
系統變數具有類似功能。在 BigQuery 中,您通常會在稽核記錄或 INFORMATION_SCHEMA
檢視畫面中檢查 numDmlAffectedRows
的傳回值。
DDL 語法
本節說明 Teradata 和 BigQuery 之間資料定義語言語法的差異。
CREATE TABLE
陳述式
大部分的 Teradata CREATE TABLE
陳述式都與 BigQuery 相容,但以下語法元素在 BigQuery 中並未使用:
MULTISET
。請參閱「CREATE INDEX
」一節。VOLATILE
。請參閱「臨時資料表」一節。[NO] FALLBACK
。請參閱「復原」一節。[NO] BEFORE JOURNAL
,[NO] AFTER JOURNAL
CHECKSUM = DEFAULT | val
DEFAULT MERGEBLOCKRATIO
PRIMARY INDEX (col, ...)
。請參閱「CREATE INDEX
」一節。UNIQUE PRIMARY INDEX
。請參閱「CREATE INDEX
」一節。CONSTRAINT
DEFAULT
IDENTITY
如要進一步瞭解 BigQuery 中的 CREATE TABLE
,請參閱 DML 說明文件中的 BigQuery CREATE
範例。
欄選項和屬性
下列 CREATE TABLE
陳述式的資料欄規格不適用於 BigQuery:
FORMAT 'format'
. 請參閱 Teradata 格式類型一節。CHARACTER SET name
。BigQuery 一律使用 UTF-8 編碼。[NOT] CASESPECIFIC
COMPRESS val | (val, ...)
Teradata 會使用資料欄 TITLE
選項擴充 ANSI 標準。這項功能也可以在 BigQuery 中使用資料欄說明來實作,如下表所示。請注意,這個選項不適用於 View。
Teradata | BigQuery |
---|---|
CREATE TABLE table ( | CREATE TABLE dataset.table ( |
臨時資料表
Teradata 支援暫時性資料表,這類資料表通常用於在指令碼中儲存中繼結果。您可以透過多種方式在 BigQuery 中建立類似於暫時性資料表的資料表:
CREATE TEMPORARY TABLE
可用於指令碼,並在指令碼的生命週期內有效。如果表格必須存在於程式碼之外,您可以使用此清單中的其他選項。資料集存留時間:建立存留時間較短的資料集 (例如 1 小時),這樣在資料集中建立的任何資料表都會是暫時性的,因為這些資料表不會保留超過資料集的存留時間。您可以為這個資料集中的所有資料表名稱加上前置字串
temp
,清楚標示這些資料表為臨時資料表。資料表 TTL:使用 DDL 陳述式建立具有資料表專屬短暫生命週期的資料表,類似於以下陳述式:
CREATE TABLE temp.name (col1, col2, ...) OPTIONS(expiration_timestamp=TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR));
WITH
子句:如果只需要在同一個區塊內使用臨時資料表,請使用WITH
陳述式或子查詢的臨時結果。這是最有效率的做法。
Teradata 指令碼 (BTEQ) 中常用的模式是建立永久資料表、插入值,在持續進行的陳述式中使用這個資料表,然後刪除或截斷資料表。實際上,這會將表格用做常數變數 (訊號量)。這種做法在 BigQuery 中效率不高,因此建議您改用 Scripting 中的實際變數,或是使用 CREATE OR REPLACE
搭配 AS SELECT
查詢語法,建立已含有值的資料表。
CREATE VIEW
陳述式
下表列出 Teradata 和 BigQuery 的 CREATE VIEW
陳述式等同項目。在 BigQuery 中,您不需要使用資料表鎖定子句,例如 LOCKING ROW FOR ACCESS
。
Teradata | BigQuery | 附註 |
---|---|---|
CREATE VIEW view_name AS SELECT ... | CREATE VIEW view_name AS SELECT ... | |
REPLACE VIEW view_name AS SELECT ... | CREATE OR REPLACE VIEW | |
不支援 | CREATE VIEW IF NOT EXISTS | 只有在檢視表目前不存在於指定資料集內時,才建立新的檢視表。 |
CREATE [UNIQUE] INDEX
陳述式
Teradata 需要所有資料表的索引,並需要特殊的解決方法 (例如 MULTISET 資料表和 NoPI 資料表) 來處理非唯一或未編入索引的資料。
BigQuery 不需要索引。本節將說明 BigQuery 中的做法,說明如何在有實際業務邏輯需求的情況下,建立類似於在 Teradata 中使用索引的功能。
為提升效能而建立索引
由於 BigQuery 是資料列導向資料庫,可針對查詢和儲存空間進行最佳化,因此不需要明確的索引。BigQuery 提供分區和分群等功能,以及巢狀欄位,可透過最佳化資料儲存方式來提升查詢效率和效能。
Teradata 不支援具體化檢視表。不過,它會使用 CREATE JOIN INDEX
陳述式提供彙整索引,這會將彙整所需的資料實體化。BigQuery 不需要實體索引就能加快效能,就像不需要專屬的 spool 空間來進行彙整一樣。
針對其他最佳化情況,您可以使用具體化檢視表。
為了保持一致性而建立索引 (UNIQUE、PRIMARY INDEX)
在 Teradata 中,您可以使用不重複索引,避免資料表中出現非不重複索引鍵的資料列。如果程序嘗試插入或更新的資料含有已在索引中出現的值,該作業會失敗並顯示索引違規 (MULTISET 資料表),或是會靜默忽略 (SET 資料表)。
由於 BigQuery 不會提供明確的索引,因此您可以改用 MERGE
陳述式,只從暫存資料表中插入唯一記錄到目標資料表,並捨棄重複的記錄。不過,由於 BigQuery 在 INSERT
作業期間不會上鎖,因此無法防止具備編輯權限的使用者插入重複的記錄。如要在 BigQuery 中產生重複記錄錯誤,您可以使用暫存資料表中的 MERGE
陳述式,如以下範例所示。
Teradata | BigQuery | |
---|---|---|
CREATE [UNIQUE] INDEX name; | MERGE `.FIN_MERGE` t |
使用者通常會自行移除重複項目,以便找出下游系統中的錯誤。
BigQuery 不支援 DEFAULT
和 IDENTITY
(序列) 欄。
索引以實現鎖定
Teradata 會在存取模組處理器 (AMP) 中提供資源;查詢可以使用所有 AMP、單一 AMP 或群組 AMP 資源。DDL 陳述式是全 AMP,因此類似於全域 DDL 鎖定。BigQuery 沒有這種鎖定機制,因此可以執行並行查詢和 INSERT
陳述式,但配額有限;只有並行的 UPDATE
DML 陳述式會產生特定並行作業影響:針對同一個區隔的 UPDATE
作業會排入佇列,以確保快照隔離,因此您不必鎖定以防發生幻影讀取或遺失更新。
由於這些差異,BigQuery 不會使用下列 Teradata 元素:
ON COMMIT DELETE ROWS;
ON COMMIT PRESERVE ROWS;
程序 SQL 陳述式
本節說明如何將在 Teradata 中用於儲存程序、函式和觸發事件的程序 SQL 陳述式,轉換為 BigQuery 指令碼、程序或使用者定義函式 (UDF)。系統管理員可以使用 INFORMATION_SCHEMA
檢視畫面查看所有這些資訊。
CREATE PROCEDURE
陳述式
BigQuery 指令碼支援預存程序。
在 BigQuery 中,指令碼是指任何控制陳述式的使用方式,而程序則是指可從其他指令碼呼叫並視需要永久儲存的命名指令碼 (必要時會附帶引數)。使用者定義函式 (UDF) 也可以使用 JavaScript 編寫。
Teradata | BigQuery |
---|---|
CREATE PROCEDURE | CREATE PROCEDURE 如果需要名稱,請使用內嵌 BEGIN 或單行 CREATE TEMP FUNCTION 。 |
REPLACE PROCEDURE | CREATE OR REPLACE PROCEDURE |
CALL | CALL |
以下各節說明如何將現有的 Teradata 程序陳述式轉換為功能相似的 BigQuery 指令碼陳述式。
變數宣告和指派
BigQuery 變數在指令碼的生命週期內有效。
Teradata | BigQuery |
---|---|
DECLARE | DECLARE |
SET | SET |
錯誤狀況處理常式
Teradata 會在程序中使用狀態代碼的處理常式來控制錯誤。在 BigQuery 中,錯誤處理是主要控制流程的核心功能,類似於其他語言透過 TRY ... CATCH
區塊提供的功能。
Teradata | BigQuery |
---|---|
DECLARE EXIT HANDLER FOR SQLEXCEPTION | BEGIN ... EXCEPTION WHEN ERROR THEN |
SIGNAL sqlstate | RAISE message |
DECLARE CONTINUE HANDLER FOR SQLSTATE VALUE 23505; | BigQuery 不會使用針對特定錯誤情況觸發的例外狀況處理常式。 建議在使用退出條件進行預先檢查或偵錯時,使用 ASSERT 陳述式,因為這符合 ANSI SQL:2011 標準。 |
Teradata 中的 SQLSTATE
變數類似於 BigQuery 中的 @@error
系統變數。在 BigQuery 中,使用稽核記錄或 INFORMATION_SCHEMA
檢視畫面,是調查錯誤的常見做法。
游標宣告和運算
由於 BigQuery 不支援游標或工作階段,因此以下陳述式無法在 BigQuery 中使用:
DECLARE cursor_name CURSOR [FOR | WITH] ...
PREPARE stmt_id FROM sql_str;
OPEN cursor_name [USING var, ...];
FETCH cursor_name INTO var, ...;
CLOSE cursor_name;
動態 SQL 陳述式
BigQuery 的指令碼功能支援動態 SQL 陳述式,例如下表所示。
Teradata | BigQuery |
---|---|
EXECUTE IMMEDIATE sql_str; | EXECUTE IMMEDIATE sql_str; |
EXECUTE stmt_id [USING var,...]; | EXECUTE IMMEDIATE stmt_id USING var; |
下列動態 SQL 陳述式不適用於 BigQuery:
PREPARE stmt_id FROM sql_str;
控制流程陳述式
BigQuery 的指令碼功能支援控制流程陳述式,例如下表所示。
Teradata | BigQuery |
---|---|
IF condition THEN stmts ELSE stmts END IF | IF condition THEN stmts ELSE stmts END IF |
label_name: LOOP stmts END LOOP label_name; | BigQuery 不使用 GOTO 式區塊結構。 建議您將這些函式改寫為使用者定義函式 (UDF),或是在用於錯誤處理的情況下使用 ASSERT 陳述式。 |
REPEAT stmts UNTIL condition END REPEAT; | WHILE condition DO stmts END WHILE |
LEAVE outer_proc_label; | LEAVE 不適用於 GOTO 樣式的區塊,而是用於 BREAK 的別名,用來離開 WHILE 迴圈。 |
LEAVE label; | LEAVE 不適用於 GOTO 樣式的區塊,而是用於 BREAK 的別名,用來離開 WHILE 迴圈。 |
WITH RECURSIVE temp_table AS ( ... ); | 在 BigQuery 中,不使用遞迴查詢 (也稱為遞迴一般資料表運算式 (CTE))。您可以使用 UNION ALL 陣列重新編寫這些值。 |
以下控制流陳述式不會在 BigQuery 中使用,因為 BigQuery 不會使用游標或工作階段:
中繼資料和交易 SQL 陳述式
Teradata | BigQuery |
---|---|
HELP TABLE table_name; HELP VIEW view_name; | SELECT 同樣的查詢可用於取得檢視畫面的欄資訊。 詳情請參閱 BigQuery 中的資料欄檢視畫面 INFORMATION_SCHEMA 。 |
SELECT * FROM dbc.tables WHERE tablekind = 'T'; (Teradata DBC 檢視畫面) | SELECT 詳情請參閱「BigQuery 簡介 INFORMATION_SCHEMA 」。 |
HELP STATISTICS table_name; | APPROX_COUNT_DISTINCT(col) |
COLLECT STATS USING SAMPLE ON table_name column (...); | 在 BigQuery 中不使用。 |
LOCKING TABLE table_name FOR EXCLUSIVE; | BigQuery 一律會使用快照隔離功能。詳情請參閱本文件其他部分的「一致性保證」一節。 |
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ... | BigQuery 一律會使用快照隔離功能。詳情請參閱本文件其他部分的「一致性保證」一節。 |
BEGIN TRANSACTION; | BigQuery 一律會使用快照隔離功能。詳情請參閱本文件其他部分的「一致性保證」一節。 |
EXPLAIN ... | 在 BigQuery 中不使用。 類似的功能包括 BigQuery 網頁版 UI 中的查詢計畫說明,以及 INFORMATION_SCHEMA 檢視畫面和 Cloud Monitoring 中的稽核記錄中顯示的時間分配。 |
BEGIN TRANSACTION; | BEGIN |
多陳述式和多行 SQL 陳述式
Teradata 和 BigQuery 都支援交易 (工作階段),因此支援以分號分隔的陳述式,並且會一併執行。詳情請參閱「多語句交易」。
錯誤代碼和訊息
Teradata 錯誤代碼和 BigQuery 錯誤代碼不同。BigQuery 提供 REST API,主要依賴 HTTP 狀態碼和詳細的錯誤訊息。
如果應用程式邏輯目前正在擷取下列錯誤,請嘗試排除錯誤來源,因為 BigQuery 不會傳回相同的錯誤代碼。
SQLSTATE = '02000'
:"找不到資料列"SQLSTATE = '21000'
:「基數違規 (不重複索引)」SQLSTATE = '22000'
:"資料違規 (資料類型)"SQLSTATE = '23000'
:「違反限制條件」
在 BigQuery 中,您通常會使用 INFORMATION_SCHEMA
檢視或稽核記錄來深入瞭解錯誤。
如要瞭解如何在指令碼中處理錯誤,請參閱後續的章節。
一致性保證和交易隔離
Teradata 和 BigQuery 都是原子式,也就是在許多資料列的每個排列層級上符合 ACID 標準。舉例來說,即使有多次插入和更新的值,MERGE
作業仍是完全原子作業。
交易
在工作階段模式 (而非自動提交模式) 中執行時,Teradata 會提供 Read Uncommitted (允許髒讀取) 或可序列化交易隔離層級。在最佳情況下,Teradata 會使用悲觀鎖定,針對所有分區的所有資料列欄,對資料列雜湊進行鎖定,藉此達成嚴格的序列化隔離。可能會發生死結。DDL 一律會強制執行交易邊界。Teradata Fastload 工作會獨立執行,但僅限於空資料表。
BigQuery 也支援交易。BigQuery 可透過快照隔離功能,確保樂觀並行控制 (先提交者勝),在該功能中,查詢會在開始查詢前讀取上次提交的資料。這種方法可確保每個資料列、每個變異數和相同 DML 陳述式中的各資料列,皆具有相同程度的一致性,同時避免發生死結。如果針對同一個資料表有多個 UPDATE
陳述式,BigQuery 會切換為悲觀並行控制,並排序多個 UPDATE
陳述式,在發生衝突時自動重試。INSERT
DML 陳述式和載入工作可同時獨立執行,以便附加至資料表。
復原
Teradata 支援兩種工作階段回溯模式,分別是 ANSI 工作階段模式和 Teradata 工作階段模式 (SET SESSION CHARACTERISTICS
和 SET SESSION TRANSACTION
),具體取決於您想要的回溯模式。在失敗情況下,系統可能不會復原交易。
BigQuery 支援 ROLLBACK TRANSACTION
陳述式。BigQuery 中沒有 ABORT
陳述式。
資料庫限制
請務必查看 BigQuery 公開說明文件 ,瞭解最新的配額和限制。如要提高大量使用者的許多配額,請與 Cloud 支援團隊聯絡。下表比較 Teradata 和 BigQuery 資料庫的限制。
限制 | Teradata | BigQuery |
---|---|---|
每個資料庫的資料表數 | 未限制 | 未限制 |
每個資料表的欄數 | 2,048 | 10,000 |
資料列大小上限 | 1 MB | 100 MB |
欄名稱長度 | 128 個 Unicode 字元 | 300 個 Unicode 字元 |
資料表說明長度 | 128 個 Unicode 字元 | 16,384 個 Unicode 字元 |
每個資料表的資料列數 | 無限制 | 無限制 |
SQL 要求長度上限 | 1 MB | 1 MB (未解析的 GoogleSQL 查詢長度上限) 12 MB (已解析的舊版和 GoogleSQL 查詢長度上限) 串流:
|
要求和回應大小上限 | 7 MB (要求)、16 MB (回應) | 10 MB (要求) 和 10 GB (回應),或使用分頁或 Cloud Storage API 時的無限空間。 |
並行工作階段數量上限 | 每個剖析引擎 (PE) 120 個 | 1,000 個並行多語句查詢 (可透過預留位置增加),每位使用者 300 個並行 API 要求。 |
並行 (快速) 載入數量上限 | 30 (預設為 5) | 沒有並行處理限制,工作會排入佇列。每個專案每日 100,000 個載入工作。 |