Teradata から BigQuery への移行: SQL 変換リファレンス

このドキュメントでは、エンタープライズ データ ウェアハウス(EDW)から Google Cloud の BigQuery への移行をスムーズに行えるように、Teradata と BigQuery の SQL 構文の類似点と違いについて詳しく説明します。Teradata データ ウェアハウジングは、Teradata 固有の SQL 構文で動作するように設計されています。サービスによって SQL 言語に違いがあるため、Teradata 用に作成したスクリプトをそのまま BigQuery で使用できない場合があります。Google Cloud パートナーには、Teradata SQL スクリプトの変換を自動化するツールが用意されています。詳しくは、アカウント担当者にお問い合わせください。

Teradata からの移行の詳細を説明するシリーズは、次のパートで構成されています。

オンプレミスのデータ ウェアハウスから Google Cloud の BigQuery への移行の概要については、データ ウェアハウスの BigQuery への移行: 導入と概要から始まるシリーズをご覧ください。

データ型

ここでは、Teradata と BigQuery の間で対応するデータ型を示します。

Teradata BigQuery
INTEGER INT64
SMALLINT INT64
BYTEINT INT64
BIGINT INT64
DECIMAL NUMERIC Teradata とは異なり、BigQuery の NUMERIC データ型はカスタムの精度または位取り(制約)を適用できません。

Teradata の計算の精度が損なわれることはありませんが、より精度の高い値を挿入して出力を丸めることができます。これにより、ANSI 標準と比較して予期しない丸め操作が発生する可能性があります。
FLOAT FLOAT64
NUMERIC NUMERIC Teradata とは異なり、BigQuery の NUMERIC データ型はカスタムの精度または位取り(制約)を適用できません。

Teradata の計算の精度が損なわれることはありませんが、より精度の高い値を挿入して出力を丸めることができます。これにより、ANSI 標準と比較して予期しない丸め操作が発生する可能性があります。
NUMBER NUMERIC Teradata とは異なり、BigQuery の NUMERIC データ型はカスタムの精度または位取り(制約)を適用できません。

Teradata の計算の精度が損なわれることはありませんが、より精度の高い値を挿入して出力を丸めることができます。これにより、ANSI 標準と比較して予期しない丸め操作が発生する可能性があります。
REAL FLOAT64
CHAR/CHARACTER STRING Teradata の CHARACTER および CHAR データ型とは異なり、BigQuery の STRING データ型は可変長であり、最大文字数を手動で設定する必要はありません。
VARCHAR STRING Teradata の VARCHAR データ型とは異なり、BigQuery の STRING データ型は可変長であり、最大文字数を手動で設定する必要はありません。
CLOB STRING
JSON STRING
BLOB BYTES
BYTE BYTES
VARBYTE BYTES
DATE DATE BigQuery では、SDF の DataForm を使用した Teradata と同様のカスタム形式設定はサポートされていません。
TIME TIME
TIME WITH TIME ZONE TIME Teradata は TIME データ型を UTC に格納し、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 型は UTC を想定します。BigQuery がインポート時に変換できるように、タイムゾーン情報を正しくエクスポートしてください(タイムゾーン情報なしで DATETIME の値を連結しないでください)。または、エクスポートする前にタイムゾーン情報を UTC に変換してください。

BigQuery には、出力時にタイムゾーンを表示しない常用時と、常に UTC タイムゾーンを表示する正確な時点である TIMESTAMP との間の抽象化のための DATETIME があります。
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) DATEDATEPERIOD(DATE) は、分析関数で使用できるように、開始日と終了日を含む 2 つの DATE 列に変換する必要があります。
PERIOD(TIMESTAMP WITH TIME ZONE) TIMESTAMPTIMESTAMP
PERIOD(TIMESTAMP) TIMESTAMPTIMESTAMP
PERIOD(TIME) TIMETIME
PERIOD(TIME WITH TIME ZONE) TIMETIME
UDT STRING
XML STRING
TD_ANYTYPE STRING

型キャストの詳細については、次のセクションをご覧ください。

Teradata 型形式

Teradata SQL では、式と列データの表示とデータ型の変換時に、デフォルト形式のセットを使用します。たとえば、INTEGERDATE モードの PERIOD(DATE) データ型の形式はデフォルトで YY/MM/DD になります。可能な限り ANSIDATE モードを使用して ANSI SQL に準拠し、この機会にレガシー フォーマットをクリーンアップすることをおすすめします。

Teradata では、DDL を使用してテーブルを作成するときのデータ型属性として、または派生式で、基になるストレージを変更せずに、FORMAT 句を使用してカスタム形式を自動的に適用できます。たとえば、FORMAT 仕様 9.99 は、FLOAT 値を 2 桁に丸めます。BigQuery では、ROUND() 関数を使用してこの機能を実装する必要があります。

この機能は、複雑なエッジケースを処理する必要があります。たとえば、FORMAT 句を NUMERIC 列に適用する場合は、アカウントの特別な丸めとフォーマットのルールを考慮する必要があります。FORMAT 句を使用すると、INTEGER エポック値を DATE 形式に暗黙的にキャストできます。または、VARCHAR 列の FORMAT 仕様 X(6) によって列の値が切り詰められるため、SUBSTR() 関数に変換する必要があります。この操作は ANSI SQL に準拠していません。そのため、列書式を BigQuery に移行しないことをおすすめします。

列書式が絶対に必要な場合は、ビューまたはユーザー定義関数(UDF)を使用します。

Teradata SQL が各データ型で使用するデフォルトの形式については、Teradata のデフォルトの形式のドキュメントをご覧ください。

タイムスタンプと日付型形式

タイムスタンプと日付形式の要素を Teradata SQL から BigQuery 標準 SQL に変換する場合は、次の表に概要を示す TIMESTAMPDATETIME のタイムゾーンの違いに注意してください。

形式(CURRENT_*)は関数ではなくキーワードであるため、Teradata 形式ではかっこを使用しません。

Teradata BigQuery
CURRENT_TIMESTAMP
CURRENT_TIME
Teradata の TIMETIMESTAMP には、WITH TIME ZONE を使用して定義された異なるタイムゾーン情報を含むことができます。 可能な場合は、ISO 形式で設定される CURRENT_TIMESTAMP() を使用します。ただし、出力形式は常に UTC タイムゾーンです(内部的には、BigQuery にはタイムゾーンがありません)。

ISO 形式の次の違いに注意してください。

DATETIME は出力チャネルの規則に基づいて形式が設定されます。BigQuery コマンドライン ツールと BigQuery コンソールでは、RFC 3339 に基づき区切り文字 T を使用して形式が設定されます。ただし Python と Java JDBC では、区切り文字にスペースが使用されます。

明示的な形式を使用する場合は、FORMAT_DATETIME() を使用して明示的なキャストを文字列にします。たとえば、次の式は常にスペース区切り文字を返します。

CAST(CURRENT_DATETIME() AS STRING)

Teradata では TIME 列で DEFAULT キーワードを使用して現在の時刻(タイムスタンプ)を設定できます。BigQuery ではこの方法を使用しません。
CURRENT_DATE 日付は、次の数式を使用して Teradata に INT64 値として保存されます。

(YEAR - 1900) * 10000 + (MONTH * 100) + DAY

日付は整数として形式設定できます。
BigQuery には、日付を常に ISO 8601 形式で返す別の DATE 形式があります。

DATE_FROM_UNIX_DATE は 1970 年をベースにしているため使用できません。

Teradata では DATE 列で DEFAULT キーワードを使用して現在の日付を設定できます。BigQuery ではこの方法を使用しません。
CURRENT_DATE-3 日付値は整数で表現されます。Teradata では日付型の算術演算子がサポートされています。 日付型の場合は、DATE_ADD() または DATE_SUB() を使用します。

BigQuery では、INT64NUMERICFLOAT64 データ型に対して算術演算子を使用します。
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
  (subquery) AS flag,
  CASE WHEN flag = 1 THEN ...
BigQuery では、列は同じ選択リスト内で定義された他の列の出力を参照できません。サブクエリを WITH 句に移動することをおすすめします。

WITH flags AS (
  subquery
),
SELECT
  CASE WHEN flags.flag = 1 THEN ...
SELECT * FROM table
WHERE A LIKE ANY ('string1', 'string2')
BigQuery では論理述語 ANY を使用しません。

複数の OR 演算子を使用して同じ機能を実現できます。

SELECT * FROM table
WHERE col LIKE 'string1' OR
      col LIKE 'string2'


この場合、文字列の比較も異なります。比較演算子をご覧ください。
SELECT TOP 10 * FROM table BigQuery は、SELECT キーワードに続く TOP n ではなく、クエリの最後に LIMIT を使用します。

比較演算子

次の表は、Teradata に固有であり、BigQuery で使用される ANSI SQL:2011 準拠の演算子に変換する必要がある Teradata の比較演算子を示しています。

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 には、2 つの文字列を比較するときに大文字と小文字を区別しないように Teradata に指示する NOT CASESPECIFIC 列属性もあります。文字列を比較する場合、BigQuery は常に大文字と小文字を区別します。たとえば、'xYz' = 'xyz' は Teradata では TRUE ですが、BigQuery では FALSE です。
exp LE exp2 exp <= exp2
exp LT exp2 exp < exp2
exp NE exp2 exp <> exp2
exp != exp2
exp GE exp2 exp >= exp2
exp GT exp2 exp > exp2

JOIN 条件

BigQuery と Teradata は同じ JOINONUSING 条件をサポートします。次の表に小さな違いの一覧を示します。

Teradata BigQuery
FROM A LEFT OUTER JOIN B ON A.date > B.start_date AND A.date < B.end_date FROM A LEFT OUTER JOIN (SELECT d FROM B JOIN UNNEST(GENERATE_DATE_ARRAY(B.start_date, B.end_date)) d) B ON A.date = B.date BigQuery では、すべての内部結合に対して、または少なくとも 1 つの等式条件(=)が指定されている場合、不等式 JOIN 句がサポートされます。ただし、OUTER JOIN 内に不等式条件(= と <)が 1 つしかない場合は、サポートされません。このような構造は、日付や整数の範囲をクエリするために使用されることがあります。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 には、2 つの文字列を比較するときに大文字と小文字を区別しないように Teradata に指示する NOT CASESPECIFIC 列属性もあります。文字列を比較する場合、BigQuery は常に大文字と小文字を区別します。たとえば、'xYz' = 'xyz' は Teradata では TRUE ですが、BigQuery では FALSE です。
CAST(long_varchar_colum AS CHAR(6)) LPAD(long_varchar_colum, 6) Teradata での文字列のキャストは、標準的かつ最適な方法ではありませんが、パディングされた部分文字列を作成するために使用されることがあります。
CAST(92617 AS TIME) 92617 (FORMAT '99:99:99') PARSE_TIME("%k%M%S", CAST(92617 AS STRING))
Teradata は BigQuery よりも暗黙的な型変換と丸めを多く実行します。BigQuery は基本的に厳密であり、ANSI 標準を適用します。
(この例では 09:26:17 が返されます)
CAST(48.5 (FORMAT 'zz') AS FLOAT) CAST(SUBSTR(CAST(48.5 AS STRING), 0, 2) AS FLOAT64)
浮動小数点および数値データ型が通貨などの形式で適用される場合、特別な丸めルールが必要となる場合があります。
(この例では 48 が返されます)

比較演算子列書式もご覧ください。比較と列書式はどちらも型キャストのように動作できます。

QUALIFY 句、ROWS 句

Teradata の QUALIFY 句を使用すると、ウィンドウ関数の結果をフィルタリングできます。または、同じタスクに ROWS フレーズを使用することもできます。これらは GROUP 句の HAVING 条件と同様に機能し、BigQuery で集計分析関数と呼ばれるものの出力を制限します。

Teradata BigQuery
SELECT col1, col2
FROM table
QUALIFY ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) = 1;
ROW_NUMBER()SUM()COUNT()OVER PARTITION BY などの分析関数を含む Teradata の QUALIFY 句は、BigQuery では分析値を含むサブクエリの WHERE 句として表現されます。

ROW_NUMBER() を使用:

SELECT col1, col2
FROM (
  SELECT col1, col2,
  ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col2) RN
  FROM table
) WHERE RN = 1;


より大きなパーティションをサポートする ARRAY_AGG を使用:

SELECT
  result.*
FROM (
  SELECT
    ARRAY_AGG(table ORDER BY table.col2
      DESC LIMIT 1)[OFFSET(0)]
  FROM table
  GROUP BY col1
) AS result;
SELECT col1, col2
FROM table
AVG(col1) OVER (PARTITION BY col1 ORDER BY col2 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW);
SELECT col1, col2
FROM table
AVG(col1) OVER (PARTITION BY col1 ORDER BY col2 RANGE BETWEEN 2 PRECEDING AND CURRENT ROW);


BigQuery では、RANGEROWS の両方をウィンドウ フレーム句で使用できます。ただし、ウィンドウ句は AVG() などの分析関数でのみ使用でき、ROW_NUMBER() などの番号付け関数では使用できません。

NORMALIZE キーワード

Teradata では、SELECT 句に NORMALIZE キーワードを使用でき、重複する期間や間隔をすべての個々の期間値を含む単一の期間または間隔にまとめることができます。

BigQuery は PERIOD 型をサポートしていないため、Teradata の PERIOD 型の列は、期間の開始日と終了日に呼応する 2 つの異なる DATE フィールドまたは DATETIME フィールドとして BigQuery に挿入する必要があります。

Teradata BigQuery
SELECT NORMALIZE
    client_id,
    item_sid,
    BEGIN(period) AS min_date,
    END(period) AS max_date,
  FROM
    table;
SELECT
  t.client_id,
  t.item_sid,
  t.min_date,
  MAX(t.dwh_valid_to) AS max_date
FROM (
  SELECT
    d1.client_id,
    d1.item_sid,
    d1.dwh_valid_to AS dwh_valid_to,
    MIN(d2.dwh_valid_from) AS min_date
  FROM
    table d1
  LEFT JOIN
    table d2
  ON
    d1.client_id = d2.client_id
    AND d1.item_sid = d2.item_sid
    AND d1.dwh_valid_to >= d2.dwh_valid_from
    AND d1.dwh_valid_from < = d2.dwh_valid_to
  GROUP BY
    d1.client_id,
    d1.item_sid,
    d1.dwh_valid_to ) t
GROUP BY
  t.client_id,
  t.item_sid,
  t.min_date;

関数

以下のセクションでは、Teradata の関数とそれに対応する BigQuery の関数を示します。

集計関数

次の表は、Teradata の一般的な集計関数、統計集計関数、近似集計関数および対応する BigQuery 関数を示しています。BigQuery では、次の集計関数も使用できます。

Teradata BigQuery
AVG AVG
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(
  IF(dep_var_expression is NULL
     OR ind_var_expression is NULL,
     NULL, ind_var_expression)
)
REGR_AVGY AVG(
  IF(dep_var_expression is NULL
     OR ind_var_expression is NULL,
     NULL, dep_var_expression)
)
REGR_COUNT SUM(
  IF(dep_var_expression is NULL
     OR ind_var_expression is NULL,
     NULL, 1)
)
REGR_INTERCEPT AVG(dep_var_expression) - AVG(ind_var_expression) * (COVAR_SAMP(ind_var_expression,
              dep_var_expression)
   / VARIANCE(ind_var_expression))
REGR_R2 (COUNT(dep_var_expression)*
 SUM(ind_var_expression * dep_var_expression) -
 SUM(dep_var_expression) * SUM(ind_var_expression))
SQRT(
     (COUNT(ind_var_expression)*
      SUM(POWER(ind_var_expression, 2))*
      POWER(SUM(ind_var_expression),2))*
     (COUNT(dep_var_expression)*
      SUM(POWER(dep_var_expression, 2))*
      POWER(SUM(dep_var_expression), 2)))
REGR_SLOPE - COVAR_SAMP(ind_var_expression,
            dep_var_expression)
/ VARIANCE(ind_var_expression)
REGR_SXX SUM(POWER(ind_var_expression, 2)) - COUNT(ind_var_expression) *
  POWER(AVG(ind_var_expression),2)
REGR_SXY SUM(ind_var_expression * dep_var_expression) - COUNT(ind_var_expression)
  * AVG(ind) * AVG(dep_var_expression)
REGR_SYY SUM(POWER(dep_var_expression, 2)) - COUNT(dep_var_expression)
  * POWER(AVG(dep_var_expression),2)
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
ARRAY_AGG ARRAY_AGG
ARRAY_CONCAT, (|| operator) ARRAY_CONCAT_AGG, (|| operator)
BITAND BIT_AND
BITNOT ビット NOT 演算子~
BITOR BIT_OR
BITXOR BIT_XOR
CORR CORR
COUNT COUNT
COVAR_POP COVAR_POP
COVAR_SAMP COVAR_SAMP
CUME_DIST CUME_DIST
DENSE_RANK(ANSI) DENSE_RANK
FIRST_VALUE FIRST_VALUE
LAST_VALUE LAST_VALUE
MAX MAX
MIN MIN
PERCENT_RANK PERCENT_RANK
PERCENTILE_CONTPERCENTILE_DISC PERCENTILE_CONTPERCENTILE_DISC
RANK(ANSI) RANK
ROW_NUMBER ROW_NUMBER
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
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 DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 MONTH
    ),
    MONTH
  ),
  INTERVAL 1 DAY )
MONTHS_BETWEEN DATE_DIFF(date_expression, date_expression, MONTH)
NEXT_DAY DATE_ADD()
  DATE_TRUNC(
    date_expression,
    WEEK(day_value)
  ),
  INTERVAL 1 WEEK
)
OADD_MONTHS DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL num_months MONTH
    ),
    MONTH
  ),
  INTERVAL 1 DAY
)
td_day_of_month EXTRACT(DAY FROM date_expression)
EXTRACT(DAY FROM timestamp_expression)
td_day_of_week EXTRACT(DAYOFWEEK FROM date_expression)
EXTRACT(DAYOFWEEK FROM timestamp_expression)
td_day_of_year EXTRACT(DAYOFYEAR FROM date_expression)
EXTRACT(DAYOFYEAR FROM timestamp_expression)
td_friday DATE_TRUNC(
  date_expression,
  WEEK(FRIDAY)
)
td_monday DATE_TRUNC(
  date_expression,
  WEEK(MONDAY)
)
td_month_begin DATE_TRUNC(date_expression, MONTH)
td_month_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 MONTH
    ),
    MONTH
  ),
  INTERVAL 1 DAY
)
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)
- ((EXTRACT(QUARTER FROM date_expression) - 1) * 3)
td_month_of_year EXTRACT(MONTH FROM date_expression)
EXTRACT(MONTH FROM timestamp_expression)
td_quarter_begin DATE_TRUNC(date_expression, QUARTER)
td_quarter_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 QUARTER
    ),
    QUARTER
  ),
  INTERVAL 1 DAY
)
td_quarter_of_calendar (EXTRACT(YEAR FROM date_expression)
- 1900) * 4
+ EXTRACT(QUARTER FROM date_expression)
td_quarter_of_year EXTRACT(QUARTER FROM date_expression)
EXTRACT(QUARTER FROM timestamp_expression)
td_saturday DATE_TRUNC(
  date_expression,
  WEEK(SATURDAY)
)
td_sunday DATE_TRUNC(
  date_expression,
  WEEK(SUNDAY)
)
td_thursday DATE_TRUNC(
  date_expression,
  WEEK(THURSDAY)
)
td_tuesday DATE_TRUNC(
  date_expression,
  WEEK(TUESDAY)
)
td_wednesday DATE_TRUNC(
  date_expression,
  WEEK(WEDNESDAY)
)
td_week_begin DATE_TRUNC(date_expression, WEEK)
td_week_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 WEEK
    ),
    WEEK
  ),
  INTERVAL 1 DAY
)
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)
- EXTRACT(WEEK FROM DATE_TRUNC(date_expression, MONTH))
td_week_of_year EXTRACT(WEEK FROM date_expression)
EXTRACT(WEEK FROM timestamp_expression)
td_weekday_of_month CAST(
  CEIL(
    EXTRACT(DAY FROM date_expression)
    / 7
  ) AS INT64
)
td_year_begin DATE_TRUNC(date_expression, YEAR)
td_year_end DATE_SUB(
  DATE_TRUNC(
    DATE_ADD(
      date_expression,
      INTERVAL 1 YEAR
    ),
    YEAR
  ),
  INTERVAL 1 DAY
)
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 では、次の文字列関数も使用できます。

Teradata BigQuery
ASCII TO_CODE_POINTS(string_expression)[OFFSET(0)]
CHAR2HEXINT TO_HEX
CHARACTER LENGTH CHAR_LENGTH
CHARACTER LENGTH CHARACTER_LENGTH
CHR CODE_POINTS_TO_STRING(
  [mod(numeric_expression, 256)]
)
CONCAT, (|| operator) CONCAT, (|| operator)
CSV カスタムのユーザー定義関数。
CSVLD カスタムのユーザー定義関数。
FORMAT FORMAT
INDEX STRPOS(string, substring)
INITCAP カスタムのユーザー定義関数。
INSTR カスタムのユーザー定義関数。
LEFT SUBSTR(source_string, 1, length)
LENGTH LENGTH
LOWER LOWER
LPAD LPAD
LTRIM LTRIM
NGRAM カスタムのユーザー定義関数。
NVP カスタムのユーザー定義関数。
OREPLACE REPLACE
OTRANSLATE カスタムのユーザー定義関数。
POSITION STRPOS(string, substring)
REGEXP_INSTR STRPOS(source_string,
REGEXP_EXTRACT(source_string, regexp_string))


: 最初の一致が返されます。
REGEXP_REPLACE REGEXP_REPLACE
REGEXP_SIMILAR IF(REGEXP_CONTAINS,1,0)
REGEXP_SUBSTR REGEXP_EXTRACT,
REGEXP_EXTRACT_ALL
REGEXP_SPLIT_TO_TABLE カスタムのユーザー定義関数。
REVERSE REVERSE
RIGHT SUBSTR(source_string, -1, length)
RPAD RPAD
RTRIM RTRIM
STRTOK

: delimiter の文字列引数の各文字は、個別の区切り文字とみなされます。デフォルトの区切り文字はスペースです。
SPLIT(instring, delimiter)[ORDINAL(tokennum)]

: delimiter の文字列引数全体が単一の区切り文字として使用されます。デフォルトの区切り文字はカンマです。
STRTOK_SPLIT_TO_TABLE カスタムのユーザー定義関数
SUBSTRINGSUBSTR SUBSTR
TRIM TRIM
UPPER UPPER

数学関数

次の表は、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)

DML 構文

ここでは、Teradata と BigQuery のデータ管理言語構文の違いについて説明します。

INSERT ステートメント

Teradata の INSERT ステートメントの大部分は BigQuery と互換性があります。次の表に例外を示します。

BigQuery の DML スクリプトは、それに対応する Teradata のステートメントとは整合性セマンティクスが少し異なります。スナップショット分離とセッションとトランザクションの処理の概要については、このドキュメントの CREATE INDEX セクションをご覧ください。

Teradata BigQuery
INSERT INTO table VALUES (...); INSERT INTO table (...) VALUES (...);

Teradata では、null 値が許可されない列に DEFAULT キーワードを使用できます。

注: BigQuery では、ターゲット テーブル内のすべての列の値が元の順序位置に基づいた昇順で挿入されている場合にのみ、INSERT ステートメントで列名を省略できます。
INSERT INTO table VALUES (1,2,3);
INSERT INTO table VALUES (4,5,6);
INSERT INTO table VALUES (7,8,9);
INSERT INTO table VALUES (1,2,3),
                         (4,5,6),
                         (7,8,9);

Teradata には、一度に複数の INSERT ステートメントを送信するマルチステートメント リクエスト(MSR)のコンセプトがあります。BigQuery では、ステートメント間に暗黙のトランザクション境界があるため、これは推奨されません。代わりに複数値 INSERT を使用してください。

BigQuery では INSERT ステートメントを同時に実行できますが、UPDATE がキューに入る場合があります。パフォーマンスを向上させるには、次の方法を検討してください。
  • INSERT オペレーションごとに 1 行ではなく、1 つの INSERT ステートメントで複数の行を組み合わせる。
  • MERGE ステートメントを使用して、複数の DML ステートメント(INSERT を含む)を組み合わせる。
  • 特にパーティション化されたフィールドロールバックまたは復元をクエリする場合、UPDATEDELETE の代わりに CREATE TABLE ... AS SELECT を使用して、新しいテーブルを作成して入力する。

UPDATE ステートメント

Teradata の UPDATE ステートメントの大部分は BigQuery と互換性がありますが、次の場合は例外です。

  • FROM 句を使用すると、Teradata と BigQuery で FROM 句と SET 句の順序が逆になる。
  • 標準 SQL では必ず、各 UPDATE ステートメントに WHERE キーワードと条件文を含める必要がある。テーブル内のすべての行を更新するには、WHERE true とします。

ベスト プラクティスとして、単一の UPDATE ステートメントと INSERT ステートメントではなく、複数の DML ミューテーションをグループ化することをおすすめします。BigQuery の DML スクリプトは、それに対応する Teradata のステートメントとは整合性セマンティクスが少し異なります。スナップショット分離とセッションとトランザクションの処理の概要については、このドキュメントの CREATE INDEX セクションをご覧ください。

次の表は、同じタスクを実行する Teradata の UPDATE ステートメントと BigQuery のステートメントを示しています。

BigQuery の UPDATE の詳細については、DML ドキュメントの BigQuery UPDATE の例をご覧ください。

Teradata BigQuery
UPDATE table_A
FROM table_A, table_B
SET
  y = table_B.y,
  z = table_B.z + 1
WHERE table_A.x = table_B.x
  AND table_A.y IS NULL;
UPDATE table_A
SET
  y = table_B.y,
  z = table_B.z + 1
FROM table_B
WHERE table_A.x = table_B.x
  AND table_A.y IS NULL;
UPDATE table alias
SET x = x + 1
WHERE f(x) IN (0, 1);
UPDATE table
SET x = x + 1
WHERE f(x) IN (0, 1);
UPDATE table_A
FROM table_A, table_BA, B
SET z = table_B.z
WHERE table_A.x = table_B.x
  AND table_A.y = table_B.y;
UPDATE table_A
SET z = table_B.z
FROM table_B
WHERE table_A.x = table_B.x
  AND table_A.y = table_B.y;

DELETE、TRUNCATE ステートメント

DELETE ステートメントと TRUNCATE ステートメントは、どちらもテーブルのスキーマやインデックスに影響を与えることなくテーブルから行を削除する方法です。TRUNCATE は Teradata と BigQuery のどちらでも使用されません。ただし、DELETE ステートメントを使用しても結果は同じです。

BigQuery では、DELETE ステートメントには WHERE 句が必要です。テーブル内のすべての行を削除(切り詰め)するには、WHERE true を使用します。非常に大きなテーブルの切り詰めオペレーションを高速化するには、同じテーブルで LIMIT 0 を使用してそれ自体を置き換えて CREATE OR REPLACE TABLE ... AS SELECT ステートメントを使用することをおすすめします。ただし、使用する場合は、パーティショニングとクラスタリングの情報を手動で追加してください。

Teradata は削除された行を後でバキュームします。つまり、DELETE オペレーションは最初は BigQuery よりも高速ですが、後でリソースが必要になります。特に、テーブルの大部分に影響する大規模な DELETE オペレーションが必要になります。BigQuery で同様のアプローチを使用する場合は、削除しない行を新しいテーブルにコピーするなどして、DELETE オペレーションの数を減らすことをおすすめします。別の方法として、パーティション全体を削除することもできます。これらのオプションはどちらも、アトミックな DML ミューテーションよりも高速なオペレーションとして設計されています。

BigQuery の DELETE の詳細については、DML ドキュメントの DELETE の例をご覧ください。

Teradata BigQuery
BEGIN TRANSACTION;
LOCKING TABLE table_A FOR EXCLUSIVE;
DELETE FROM table_A;
INSERT INTO table_A SELECT * FROM table_B;
END 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 ステートメントでは、INSERTUPDATEDELETE オペレーションを 1 つの「upsert」ステートメントに組み合わせて、アトミックに実行できます。MERGE 操作では、ターゲット行ごとに最大 1 つのソース行を対応させる必要があります。BigQuery と Teradata はどちらも ANSI 構文に準拠します。

Teradata の MERGE オペレーションは、1 つのアクセス モジュール プロセッサ(AMP)内では一致する主キーに制限されます。一方、BigQuery には MERGE オペレーションのサイズや列の制限がないため、MERGE の使用が最適化に役立ちます。ただし、MERGE が大規模な削除である場合は、このドキュメントの DELETE の最適化をご覧ください。

BigQuery の DML スクリプトは、それに対応する Teradata のステートメントとは整合性セマンティクスが少し異なります。たとえば、セッション モードの Teradata の SET テーブルは、MERGE オペレーション中に重複を無視する場合があります。MULTISET テーブルと SET テーブルの処理、スナップショット分離、セッションとトランザクションの処理の概要については、このドキュメントの CREATE INDEX セクションをご覧ください。

影響を受ける行の変数

ACTIVITY_COUNT 変数は Teradata の ANSI SQL 拡張機能であり、DML ステートメントの影響を受けた行数が入力されます。

スクリプト機能@@row_count システム変数に、同様の機能があります。BigQuery では、監査ログまたは INFORMATION_SCHEMA ビューで numDmlAffectedRows の戻り値を確認する方が一般的です。

DDL 構文

このセクションでは、Teradata と BigQuery のデータ定義言語構文の違いについて説明します。

CREATE TABLE ステートメント

Teradata の CREATE TABLE ステートメントの大部分は、BigQuery と互換性がありますが、例外として次の構文要素は BigQuery で使用されません。

BigQuery の CREATE TABLE の詳細については、DML ドキュメントの BigQuery CREATE の例をご覧ください。

列のオプションと属性

次の CREATE TABLE ステートメントの列仕様は BigQuery では使用されません。

Teradata は、列 TITLE オプションを使用して ANSI 標準を拡張します。BigQuery では、次の表に示すように列の説明を使用することで、同様の機能を実装できます。このオプションはビューでは使用できないことに注意してください。

Teradata BigQuery
CREATE TABLE table (
col1 VARCHAR(30) TITLE 'column desc'
);
CREATE TABLE dataset.table (
  col1 STRING
OPTIONS(description="column desc")
);

一時テーブル

Teradata では、揮発性テーブルがサポートされています。これは、スクリプトに中間結果を格納するためによく使用されます。BigQuery で揮発性テーブルに似た動作を実現するための方法はいくつかあります。

  • CREATE TEMPORARY TABLEスクリプトで使用でき、スクリプトの存続期間中は有効です。テーブルがスクリプト以外に存在する必要がある場合は、このリストの他のオプションを使用できます。

  • データセット TTL: 短い有効期間(たとえば 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 では効率的ではないため、代わりにスクリプト実際の変数を使用するか、AS SELECT クエリ構文で CREATE OR REPLACE を使用して、すでに値が含まれているテーブルを作成することをおすすめします。

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
view_name AS
SELECT ...
非対応 CREATE VIEW IF NOT EXISTS
OPTIONS(view_option_list)
AS SELECT ...
指定されたデータセット内に現在ビューが存在しない場合にのみ、新しいビューを作成します。

CREATE [UNIQUE] INDEX ステートメント

Teradata ではすべてのテーブルのインデックスが必要で、一意でないデータやインデックス付きでないデータを処理するために MULTISET テーブルや NoPI テーブルなどの特別な回避策が必要です。

BigQuery ではインデックスは不要です。このセクションでは、実際のビジネス ロジックで Teradata のインデックスを使用する場合と同様の機能を BigQuery で実現する方法について説明します。

パフォーマンス向上のためのインデックス作成

BigQuery は、クエリとストレージの最適化を備えた列指向のデータベースであるため、明示的なインデックスは必要ありません。BigQuery では、パーティショニングとクラスタリング、さらにネストされたフィールドなどの機能を使用できます。これらを使用してデータの格納方法を最適化することで、クエリの効率とパフォーマンスが向上します。

Teradata は、マテリアライズド ビューをサポートしていません。ただし、CREATE JOIN INDEX ステートメントを使用して結合インデックスを実現できます。これにより、結合に必要なデータが実質的に実体化されます。BigQuery では、結合のための専用のスプール スペースが必要ないのと同様に、パフォーマンスを高速化するためのマテリアライズド インデックスを必要としません。

その他の最適化のケースでは、マテリアライズド ビューを使用できます。

整合性向上のためのインデックス作成(UNIQUE、PRIMARY INDEX)

Teradata では、テーブル内に一意でないキーを持つ行がないようにするため、一意のインデックスを使用できます。すでにインデックスにある値を持つデータを挿入または更新しようとすると、オペレーションはインデックス違反で失敗するか(MULTISET テーブル)、通知なしでデータを無視します(SET テーブル)。

BigQuery は明示的なインデックスを提供しないため、代わりに MERGE ステートメントを使用して、ステージング テーブルからターゲット テーブルに一意のレコードのみを挿入すると同時に、重複レコードを破棄できます。ただし、編集権限を持つユーザーが重複レコードを挿入しないようにする方法はありません。これは、BigQuery が INSERT オペレーション中にロックを行わないためです。BigQuery で重複レコードのエラーを生成するには、次の例に示すように、ステージング テーブルから MERGE ステートメントを使用します。

Teradata BigQuery
CREATE [UNIQUE] INDEX name; MERGE `prototype.FIN_MERGE` t
USING `prototype.FIN_TEMP_IMPORT` m
ON t.col1 = m.col1
  AND t.col2 = m.col2
WHEN MATCHED THEN
  UPDATE SET t.col1 = ERROR(CONCAT('Encountered error for ', m.col1, ' ', m.col2))
WHEN NOT MATCHED THEN
  INSERT (col1,col2,col3,col4,col5,col6,col7,col8) VALUES(col1,col2,col3,col4,col5,col6,CURRENT_TIMESTAMP(),CURRENT_TIMESTAMP());

ダウンストリーム システムのエラーを見つけるため、ユーザーは個別に重複を排除することを選ぶ場合がよくあります。
BigQuery は DEFAULT 列と IDENTITY(シーケンス)をサポートしていません。

ロックを実現するためのインデックス作成

Teradata はアクセス モジュール プロセッサ(AMP)にリソースを提供します。クエリは、すべての AMP リソース、単一の AMP リソース、グループの AMP リソースを使用できます。DDL ステートメントの対象はすべての AMP に及ぶため、グローバル DDL ロックに似ています。BigQuery にはこのようなロック メカニズムがなく、割り当てに達するまでクエリと INSERT ステートメントを同時に実行でき、同時実行される UPDATE DML ステートメントのみが同時実行の影響を受けます。同じパーティションに対する UPDATE オペレーションは、スナップショット分離を確保するためにキューに入れられるため、ファントム リードやロスト アップデートを防止するためにロックする必要はありません。

これらの違いのため、次の Teradata 要素は BigQuery では使用されません。

  • ON COMMIT DELETE ROWS;
  • ON COMMIT PRESERVE ROWS;

手続き型 SQL ステートメント

このセクションでは、ストアド プロシージャ、関数、トリガーで使用される手続き型 SQL ステートメントを Teradata から BigQuery スクリプト、プロシージャ、またはユーザー定義関数(UDF)に変換する方法について説明します。これらはすべて、システム管理者が INFORMATION_SCHEMA ビューを使用して確認できるようになっています。

CREATE PROCEDURE ステートメント

ストアド プロシージャは、BigQuery スクリプトの一部としてサポートされています。

BigQuery では、スクリプトは制御ステートメントの使用すべてを指しますが、プロシージャは他のスクリプトから呼び出して必要に応じて永続的に保存できる名前付きスクリプト(該当する場合は引数を含む)です。ユーザー定義関数(UDF)も JavaScript で記述できます。

Teradata BigQuery
CREATE PROCEDURE CREATE PROCEDURE(名前が必要な場合)。そうでない場合は BEGIN とインラインで使用するか、CREATE TEMP FUNCTION と 1 行で使用します。
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 では使用されません。

ANSI SQL:2011 に準拠しているため、事前チェックやデバッグのために終了条件を使用する ASSERT ステートメントを使用することをおすすめします。

Teradata の SQLSTATE 変数は、BigQuery の @@error システム変数に似ています。BigQuery では、監査ロギングまたは INFORMATION_SCHEMA ビューでエラーを調査することが一般的です。

カーソル宣言と演算子

BigQuery ではカーソルやセッションがサポートされていないため、次のステートメントは BigQuery では使用されません。

動的 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 では使用されません。

フロー制御ステートメント

BigQuery のスクリプト機能は、次の表に示すようなフロー制御ステートメントをサポートしています。

Teradata BigQuery
IF condition THEN stmts ELSE stmts END IF IF condition THEN stmts ELSE stmts END IF
label: LOOP stmts END LOOP label; GOTO スタイルのブロック構造は BigQuery では使用されません。

ユーザー定義関数(UDF)として書き換えるか、エラー処理に使用する ASSERT ステートメントを使用することをおすすめします。
REPEAT stmts UNTIL condition END REPEAT; WHILE condition DO stmts END WHILE
LEAVE outer_proc_label; LEAVE は GOTO スタイルのブロックには使用されません。BREAKWHILE ループ離脱の同義語として使用されます。
LEAVE label; LEAVE は GOTO スタイルのブロックには使用されません。BREAKWHILE ループ離脱の同義語として使用されます。
WITH RECURSIVE temp_table AS ( ... ); 再帰クエリ(再帰的な共通テーブル式(CTE)とも呼ばれる)は、BigQuery では使用されません。これらは、UNION ALL の配列を使用して書き換えることが可能です。

BigQuery でカーソルやセッションが使用されないため、次のフロー制御ステートメントは BigQuery では使用されません。

メタデータおよびトランザクション SQL ステートメント

Teradata BigQuery
HELP TABLE table_name;
HELP VIEW view_name;
SELECT
 * EXCEPT(is_generated, generation_expression, is_stored, is_updatable)
FROM
 mydataset.INFORMATION_SCHEMA.COLUMNS;
WHERE
 table_name=table_name


同じクエリを使用してビューの列情報を取得できます。
詳細については、BigQuery INFORMATION_SCHEMA の列ビューをご覧ください。
SELECT * FROM dbc.tables WHERE tablekind = 'T';

(Teradata DBC ビュー)
SELECT
 * EXCEPT(is_typed)
FROM
mydataset.INFORMATION_SCHEMA.TABLES;


詳細については、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;
SELECT ...
END TRANSACTION;
BigQuery では、常にスナップショット分離が使用されます。詳しくは、このドキュメントの整合性の保証についての説明をご覧ください。
EXPLAIN ... BigQuery では使用されません。

同様の機能には、BigQuery ウェブ UI のクエリプランの説明INFORMATION_SCHEMA ビューおよび Cloud Monitoring の監査ログに表示されるスロット割り当てがあります。

複数ステートメントおよび複数行 SQL ステートメント

Teradata ではトランザクション(セッション)がサポートされるため、セミコロンで区切られたステートメントが一貫して一緒に実行されます。BigQuery はスクリプト機能で同じものをサポートしていますが、これらのステートメントはロールバックなしの個別のクエリとして実行されます。

エラーコードとメッセージ

Teradata のエラーコードと BigQuery のエラーコードは異なります。REST API を提供する BigQuery は、主に HTTP ステータス コードと詳細なエラー メッセージに依存しています。

アプリケーション ロジックによって現在以下のエラーが検出される場合は、エラーの原因を排除してください。BigQuery は同じエラーコードを返しません。

  • SQLSTATE = '02000' - 「Row not found」
  • SQLSTATE = '21000' - 「Cardinality violation (Unique Index)」
  • SQLSTATE = '22000' - 「Data violation (Data Type)」
  • SQLSTATE = '23000' - 「Constraint Violation」

BigQuery では、INFORMATION_SCHEMA ビューまたは監査ログを使用してエラーをドリルダウンするのが一般的です。

スクリプトのエラーを処理する方法については、以降のセクションをご覧ください。

整合性の保証とトランザクション分離

Teradata と BigQuery はどちらもアトミックです。つまり、多数の行にわたってミューテーション単位で ACID に準拠しています。たとえば MERGE オペレーションは、複数の値を挿入、更新していても、完全にアトミックです。

トランザクション

Teradata では、セッション モード(自動 commit モードではない)での実行時に、確定されていないデータの読み取り(ダーティリードの許可)またはシリアル化可能なトランザクション分離レベルがあります。最良のシナリオでは、Teradata は、パーティション全体の行の全列の行ハッシュに対して悲観的ロックを使用することにより、厳密にシリアル化可能な分離を実現します。デッドロックが発生する可能性があります。DDL は常にトランザクション境界を適用します。Teradata Fastload ジョブは独立して実行されますが、空のテーブルでのみ実行されます。

BigQuery では、スナップショット分離を使用して、楽観的同時実行制御(最初の commit が優先)が確実に実行されるようにします。この場合、クエリは、クエリが開始される前に最後に commit されたデータを読み取ります。この方法により、行ごと、ミューテーションごと、同じ DML ステートメント内の行全体で、同じレベルの整合性が保証され、デッドロックも回避されます。同じテーブルに対する複数の UPDATE ステートメントの場合、BigQuery は悲観的同時実行制御に切り替え、複数の UPDATE ステートメントをキューに入れて、競合が発生した場合に自動的に再試行します。INSERT DML ステートメントと読み込みジョブは、同時かつ独立して実行され、テーブルへの連結を実行できます。しかし BigQuery では、明示的な手動のトランザクション境界もセッションも提供されていません。

ロールバック

Teradata では、2 つのセッション ロールバック モード、ANSI セッション モードおよび Teradata セッション モード(SET SESSION CHARACTERISTICS および SET SESSION TRANSACTION)が利用でき、必要なロールバック モードに応じて使い分けることができます。失敗した場合、トランザクションがロールバックされない場合があります。

BigQuery のスクリプト機能を使用すると、ステートメントのシリアル依存実行が可能ですが、後の更新が失敗した場合はロールバックされません。

BigQuery には ABORT ステートメントおよび ROLLBACK ステートメントはありません。

BigQuery にはまだ明示的なトランザクション境界がないため、明示的なロールバックのコンセプトもありません。BigQuery では、テーブル デコレータまたは FOR SYSTEM_TIME AS OF 句(「タイムトラベル」機能)を使用することをおすすめします。このようにして、DDL 変更を含むバッチ実行の前のスナップショットを個別かつ明示的に定義できます。BigQuery ではタイムトラベルが常に追加費用なしで有効になるため、FALLBACK を明示的に指定することや、スプーリングやジャーナリングを最適化する必要はありません。

データベースに関する上限

最新の割り当てと上限については、必ず BigQuery の公開ドキュメントを確認してください。大量のユーザーに多数の割り当てを行う場合は、Cloud サポートチームに連絡して上限を引き上げることができます。次の表に、Teradata と BigQuery のデータベースに関する上限の比較を示します。

上限 Teradata BigQuery
データベースあたりのテーブル数 上限なし 上限なし
テーブルあたりの列数 2,048 10,000
行の最大サイズ 1 MB 100 MB
列とテーブルの名前の長さ 128 Unicode 文字 16,384 Unicode 文字
テーブルあたりの行数 上限なし 上限なし
SQL リクエストの最大長 1 MB 1 MB(未解決標準 SQL クエリの最大長)
12 MB(解決済みレガシーおよび標準 SQL クエリの最大長)

ストリーミング:
  • 10 MB(HTTP リクエスト サイズの上限)
  • 10,000(1 リクエストあたりの最大行数)
リクエストとレスポンスの最大サイズ 7 MB(リクエスト)、16 MB(レスポンス) 10 MB(リクエスト)と 10 GB(レスポンス)、ページ分割または Cloud Storage API を使用する場合は事実上無制限
同時実行セッションの最大数 解析エンジン(PE)あたり 120 100 同時実行クエリ(スロット予約で増やすことができます)、1 ユーザーあたり 300 同時実行 API リクエスト
同時実行(高速)読み込みの最大数 30(デフォルト 5) 同時実行の制限はありません。ジョブはキューに格納されます。プロジェクトごとに 1 日あたり 100,000 読み込みジョブ