1. 標準 SQL:LEFT JOIN
単一行の値
条件を使用して値の行を取得できLEFT JOIN
ます (それにより、一度評価されます)。次に、を使用して列ごとにフォールバック値を追加できます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
は1行なので、特に条件をつけずに結合しても問題ありません。
サブクエリでは明示的な型キャストが必要です。私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. 行型を分解する
カスタム複合型 (行型) を使用して、さまざまな型の値を保持し、それを単に *-outer で展開できSELECT
ます。text
、integer
およびの 3 つの列があるとし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 回評価されます。評価が自明でない場合は、サブクエリを使用した他のバリアントの方が高速です。