1。標準SQL:LEFT JOIN
値の単一行
LEFT JOIN
条件を使用した値の行(これにより、条件を1回評価します)。次に、を使用して、列ごとにフォールバック値を追加できます。 COALESCE()
。
この構文バリアントは、複数の値を使用すると短く、わずかに高速になります。特に、高価で長い条件の場合は興味深いものです。
SELECT COALESCE(x.txt1, trim(r2.team_name)) AS testing_testing
, COALESCE(x.txt2, trim(r2.normal_data)) AS test_response
, COALESCE(x.txt3, trim(r2.normal_data_2)) AS another_example
FROM rtp
JOIN rtd2 r2 ON <unknown condition> -- missing context in question
LEFT JOIN (
SELECT 'testing'::text AS txt1
, 'test example'::text AS txt2
, 'test example #2'::text AS txt3
) x ON rtp.team_id = rtp.sub_team_id;
派生テーブルx
以降 シングルで構成されます 行、それ以上の条件なしで参加することは問題ありません。
明示的な型キャスト サブクエリで必要です。 text
を使用しています 例では(とにかく文字列リテラルのデフォルトです)。実際のデータ型を使用してください。構文ショートカットvalue::type
Postgres固有であるため、cast(value AS type)
を使用します 標準SQLの場合。
条件がTRUE
でない場合 、x
のすべての値 NULLであり、COALESCE
キックインします。
または 、すべての候補値はテーブルrtd2
から取得されるため 特定のケースでは、LEFT JOIN
rtd2
へ 元のCASE
を使用する 条件とCROSS JOIN
デフォルト値の行へ:
SELECT COALESCE(trim(r2.team_name), x.txt1) AS testing_testing
, COALESCE(trim(r2.normal_data), x.txt2) AS test_response
, COALESCE(trim(r2.normal_data_2), x.txt3) AS another_example
FROM rtp
LEFT JOIN rtd2 r2 ON <unknown condition> -- missing context in question
AND rtp.team_id = rtp.sub_team_id
CROSS JOIN (
SELECT 'testing'::text AS txt1
, 'test example'::text AS txt2
, 'test example #2'::text AS txt3
) x;
結合条件と残りのクエリによって異なります。
2。 PostgreSQL固有
2a。配列を展開する
さまざまな列が同じデータ型を共有している場合 、サブクエリで配列を使用し、外側のSELECT
で配列を展開できます :
SELECT x.combo[1], x.combo[2], x.combo[3]
FROM (
SELECT CASE WHEN rtp.team_id = rtp.sub_team_id
THEN '{test1,test2,test3}'::text[]
ELSE ARRAY[trim(r2.team_name)
, trim(r2.normal_data)
, trim(r2.normal_data_2)]
END AS combo
FROM rtp
JOIN rtd2 r2 ON <unknown condition>
) x;
列が同じデータ型を共有していない場合は、さらに複雑になります。それらすべてをtext
にキャストすることができます (オプションで、外側のSELECT
に変換し直します )、またはできます...
2b。行タイプを分解します
カスタム複合型(行型)を使用してさまざまな型の値を保持し、それを外側のSELECT
で単純に*展開できます。 。 text
の3つの列があるとします。 、integer
およびdate
。 繰り返しの場合 使用して、カスタム複合タイプを作成します:
CREATE TYPE my_type (t1 text, t2 int, t3 date);
または 既存のテーブルのタイプが一致する場合は、テーブル名を複合タイプとして使用できます。
または タイプが一時的に必要な場合のみ 、TEMPORARY TABLE
を作成できます 、セッションの期間中の一時タイプを登録します :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
単一のトランザクションに対してこれを行うこともできます :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
次に、次のクエリを使用できます:
SELECT (x.combo).* -- parenthesis required
FROM (
SELECT CASE WHEN rtp.team_id = rtp.sub_team_id
THEN ('test', 3, now()::date)::my_type -- example values
ELSE (r2.team_name
, r2.int_col
, r2.date_col)::my_type
END AS combo
FROM rtp
JOIN rtd2 r2 ON <unknown condition>
) x;
または単に(上記と同じ、より単純、より短く、おそらく理解しにくい):
SELECT (CASE WHEN rtp.team_id = rtp.sub_team_id
THEN ('test', 3, now()::date)::my_type
ELSE (r2.team_name, r2.int_col, r2.date_col)::my_type
END).*
FROM rtp
JOIN rtd2 r2 ON <unknown condition>;
CASE
この方法では、式は列ごとに1回評価されます。評価が簡単でない場合は、サブクエリを使用した他のバリアントの方が高速になります。