再利用可能な列エイリアスを使用する

BigQuery の GoogleSQL は、再利用可能な列エイリアスをサポートしています。再利用可能な列エイリアスを使用すると、SQL クエリの SELECT 句で式のエイリアスを定義し、同じ SELECT リスト内または同じクエリブロックの WHERE 句内でそのエイリアスをすぐに参照できます。

たとえば、次のクエリは、gross_price などの計算に基づいて結果をフィルタする方法を示しています。WHERE 句で計算を繰り返したり、サブクエリを使用したりする代わりに、WHERE 句でエイリアス gross_price を直接参照できます。

SELECT
  net_price * 1.23 as gross_price
FROM
  product
WHERE
  gross_price < 10.0

再利用可能な列エイリアスには、次のようなメリットがあります。

  • 簡略化された SQL 構文: 複雑な式を繰り返したり、クエリをサブクエリでラップしたりすることなく、簡潔でわかりやすい左から右への計算を記述できます。
  • 読みやすさの向上: アナリストとデベロッパーは、式を一度宣言すれば、すぐに再利用できます。これにより、クエリの読み取り、デバッグ、メンテナンスが容易になります。

再利用可能な列エイリアスを有効または無効にする

デフォルトでは、再利用可能な列エイリアスは無効になっています。列エイリアスを使用するには、BigQuery 管理者が次のいずれかのデータ定義言語(DDL)ステートメントを使用して reusable_column_aliases_mode オプションを on に設定し、この機能を有効にする必要があります。

この構成オプションを設定するには、BigQuery 管理者(roles/bigquery.admin)ロール、プロジェクトに対する bigquery.projects.update 権限、または組織に対する bigquery.organizations.update 権限が必要です。構成オプションの設定に必要な権限については、[構成設定の管理] ページの必要な権限をご覧ください。

再利用可能な列エイリアスを無効にするには、reusable_column_aliases_mode を off に設定します。値を NULL に設定すると、システムのデフォルトが使用され、この機能も無効になります。

例

組織レベルで再利用可能な列エイリアスを有効にするには、次の DDL ステートメントを入力します。

ALTER ORGANIZATION
SET OPTIONS (
  `region-<code><var>REGION</var></code>.reusable_column_aliases_mode` = "on"
);

REGION は実際のリージョンに置き換えます。

プロジェクト レベルで再利用可能な列エイリアスを有効にするには、次の DDL ステートメントを入力します。

ALTER PROJECT <code><var>PROJECT_ID</var></code>
SET OPTIONS (
  `region-<code><var>REGION</var></code>.reusable_column_aliases_mode` = "on"
);

次のように置き換えます。

  • REGION: リージョン。
  • PROJECT_ID: プロジェクト ID。

列エイリアスが有効か無効かを確認する

再利用可能な列エイリアスがプロジェクト レベルまたは組織レベルで有効になっているかどうかを確認するには、次の情報スキーマ ビューをクエリします。

情報スキーマ ビューの操作の詳細については、INFORMATION_SCHEMA の概要をご覧ください。

再利用可能な列エイリアスの使用方法

WHERE 句または SELECT 句で、エイリアス(式に割り当てられた識別子)を使用できます。

  • WHERE 句: SELECT リストで定義された計算列に基づくフィルタリング。
  • SELECT 句: 計算されたエイリアスを使用して、同じプロジェクション リスト内で別のエイリアスを定義するか、クエリによって返されるデータを決定します。

例

この例では、再利用可能な列エイリアスを使用して、SELECT リストで定義した別の計算に基づいて値を計算する方法を示します。このクエリでは、WHERE 句でエイリアスを参照する方法も示しています。

SELECT
  net_price * 1.23 as gross_price,
  gross_price * 0.5 as discounted_gross_price
FROM
  product
WHERE
  discounted_gross_price < 10.0;

クエリ名解決順序の動作変更(セマンティック ドリフト)

識別子名は、テーブルの物理列として、また作成したエイリアスとして存在できます。そのため、クエリの名前解決の順序を考慮する必要があります。BigQuery は、次の順序で名前を解決します。

  1. 列名: テーブル内の既存の列は常に優先度が最も高くなります。
  2. エイリアス: クエリで定義されたエイリアス。
  3. 外部クエリ列: 親クエリの列。
  4. 関数引数: ユーザー定義関数(UDF)またはテーブル値関数(TVF)内で実行されている場合。
  5. スクリプト変数: スクリプトで定義された変数。

この順序に基づき、テーブルに gross_price という名前の列があり、gross_price という名前のエイリアスを作成すると、クエリはエイリアスではなく列値を使用します。

つまり、SELECT 句で定義したエイリアスと同じ名前の外部クエリ列、関数引数、スクリプト変数がある場合、BigQuery は変数や引数の代わりにエイリアス値を使用して計算を行います。

名前解決順序の仕組みの例

次の例は、名前の競合がある場合に、再利用可能な列エイリアスで名前解決の順序がどのように機能するかを示しています。

外部クエリ列との競合

再利用可能な列エイリアスを有効にしていない場合、外側のクエリの列と同じ名前の SELECT 句で定義されたエイリアスは、外側のクエリの列が使用されます。再利用可能な列エイリアスが有効になっている場合、エイリアスはクエリ スコープ内の外部クエリ列を「シャドウ」します。

次の例では、ネストされたクエリでエイリアスを使用し、外部クエリの列にアクセスしています。

SELECT
  name,
  net_price,
  category_id, -- table product has category_id column
  (SELECT 100 AS category_id -- alias defined with the same name
     FROM category c
     WHERE
       id = category_id  -- Now the alias category_id is used here, not the outer query column
  ) as X
FROM
  product;

再利用可能な列エイリアスを有効にしない場合、サブクエリは外側のクエリの product テーブルの category_id 列を使用します。その結果、category_id 値は行ごとに異なります。再利用可能な列エイリアスを有効にすると、クエリはすべての行に 100 のエイリアス値を使用します。

関数の引数との競合

クエリがユーザー定義関数(UDF)内で実行されている場合、そのクエリ内で定義されたエイリアスは関数の引数よりも優先されます。

次の例では、calculate_metric 関数に val という名前の入力引数があります。

CREATE TEMP FUNCTION calculate_metric(val INT64) AS ((
  SELECT AS STRUCT
    5 AS val,       -- Alias defined as constant 5
    val + 10        -- Reference to 'val'
));

-- Calling the function with argument 100
SELECT calculate_metric(100);

再利用可能な列エイリアスを有効にしない場合、クエリは関数に渡された引数値(100)を使用し、結果は 110 (100 + 10) として計算されます。再利用可能な列エイリアスを有効にすると、クエリは SELECT リスト(5)で定義されたエイリアスを使用し、結果は 15 (5 + 10) として計算されます。

スクリプト変数との競合

再利用可能な列エイリアスを有効にしていない場合、SELECT 句で定義されたエイリアスがスクリプト変数と同じ名前であると、スクリプト変数が使用されます。再利用可能な列エイリアスを有効にすると、エイリアスはクエリ スコープ内の変数をシャドーイングします。

次の例では、デフォルト値が 10.0 の gross_price という変数を宣言しています。このクエリは、列を計算し、gross_price というエイリアスを付けます。

DECLARE gross_price NUMERIC DEFAULT 10.0;

SELECT
  net_price * 1.23 AS gross_price,
  -- Usage of 'gross_price' here determines the behavior
  gross_price * 0.5 AS discounted_gross_price
FROM
  product;

再利用可能な列エイリアスを有効にしない場合、クエリは 10.0 の変数値を使用します。結果は、すべての行で定数となる 5.0 の discounted_gross_price 値です。結果は 10.0 * 0.5 = 5.0 として計算されます。

再利用可能な列エイリアスを有効にすると、クエリは net_price * 1.23 のエイリアス値を使用します。結果は、行ごとに異なる discounted_gross_price 値になります。結果は (net_price * 1.23) * 0.5 として計算されます。

ベスト プラクティス

再利用可能な列エイリアスを使用する場合は、次のベスト プラクティスを考慮してください。

  • 再利用可能な列エイリアスを有効にする前に、既存のワークロードへの影響を評価します。
  • 意図しない動作やサイレントな動作変更(セマンティック ドリフト)を防ぐため、スクリプト変数、関数引数、外部クエリの列の名前をエイリアスの名前として使用しないでください。
  • Teradata や Snowflake などのエイリアス セマンティクスをサポートするソース言語から SQL を移行する場合は、移行を開始する前に SQL 変換の手順に沿って操作します。

列エイリアスのトラブルシューティング

次の例は、再利用可能な列エイリアスに関する一般的な問題のトラブルシューティング方法を示しています。

問題: 予期しないクエリ結果が返されるか、エイリアスが無視されているように見える。

解決策: 名前解決の順序を確認します。テーブルにエイリアスと同じ名前の列が含まれている場合、列名がエイリアスよりも優先されます。この競合を回避するには、エイリアスに一意の名前を付けます。

エラー: Column not found。

解決策: 前方参照を使用していないことを確認します。参照できるのは、使用前に定義されたエイリアスのみです。これは左から右に評価されます。

エラー: Column name is ambiguous。

解決策: エイリアス名が参照される前に、同じ SELECT リスト内で複数回定義されていないことを確認します。

制限事項

再利用可能な列エイリアスには次の制限があります。

  • クエリにグループ化または集計が含まれている場合、集計されていない式(グループ化列またはグループ化列のプロジェクション)のエイリアスは、WHERE 句または集計関数の引数として使用できません。次のクエリでは、エイリアス b が、グループ化列である a を含む式を不適切に参照しています。

    SELECT a+1 as b, sum(b) -- sum(b) is invalid.
    FROM t
    WHERE b > 5         -- Referencing b under WHERE clause is not allowed.
    GROUP BY a
    
  • 集計関数またはウィンドウ関数を直接的または推移的に参照するエイリアスは、WHERE 句で使用することも、他の集計関数の引数として使用することもできません。次のクエリでは、エイリアス x が集計関数を不適切に参照しています。

    SELECT sum(a) AS x, sum(x) -- sum(x) is invalid.
    FROM t
    WHERE x > 0          -- Referencing x under WHERE clause is not allowed.
    
  • 別のウィンドウ関数を直接的または推移的に参照するエイリアスにウィンドウ関数を適用することはできません。次のクエリでは、エイリアス x が無効なウィンドウ関数を参照しています。

    SELECT count(*) over() AS x, sum(x) over() -- sum(x) over() is invalid.
    FROM t
    
  • 再利用可能な列エイリアスは、パイプ構文ではサポートされていません。

  • 再利用可能な列エイリアスは、Graph Query Language(GQL)ではサポートされていません。