1. Standard-SQL:LEFT JOIN eine einzelne Reihe von Werten
Sie könnten LEFT JOIN
eine Reihe von Werten, die die Bedingung verwenden (wodurch sie einmal ausgewertet wird). Dann können Sie Fallback-Werte pro Spalte mit hinzufügen COALESCE()
.
Diese Syntaxvariante ist kürzer und bei mehreren Werten etwas schneller - besonders interessant für eine teure / langwierige Bedingung:
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;
Da die abgeleitete Tabelle x besteht aus einer einzelnen Zeile, Beitritt ohne weitere Bedingungen ist in Ordnung.
Explizite Typumwandlungen sind in der Unterabfrage erforderlich. Ich verwende text im Beispiel (was sowieso der Standard für String-Literale ist). Verwenden Sie Ihre tatsächlichen Datentypen. Die Syntaxverknüpfung value::type Postgres-spezifisch ist, verwenden Sie cast(value AS type) für Standard-SQL.
Wenn die Bedingung nicht TRUE ist , alle Werte in x sind NULL und COALESCE tritt ein.
Oder , da alle Kandidatenwerte aus der Tabelle rtd2 stammen in Ihrem speziellen Fall LEFT JOIN zu rtd2 unter Verwendung des ursprünglichen CASE Bedingung und CROSS JOIN zu einer Zeile mit Standardwerten:
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;
Dies hängt von den Join-Bedingungen und dem Rest der Abfrage ab.
2. PostgreSQL-spezifisch
2a. Erweitern Sie ein Array
Wenn Ihre verschiedenen Spalten den gleichen Datentyp gemeinsam haben , können Sie ein Array in einer Unterabfrage verwenden und es im äußeren SELECT erweitern :
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;
Komplizierter wird es, wenn die Spalten nicht den gleichen Datentyp haben. Sie können sie entweder alle in text umwandeln (und optional im äußeren SELECT zurückwandeln ), oder Sie können ...
2b. Einen Zeilentyp zerlegen
Sie können einen benutzerdefinierten zusammengesetzten Typ (Zeilentyp) verwenden, um Werte verschiedener Typen aufzunehmen, und ihn einfach im äußeren SELECT mit * erweitern . Angenommen, wir haben drei Spalten:text , integer und date . Für wiederholt verwenden, erstellen Sie einen benutzerdefinierten zusammengesetzten Typ:
CREATE TYPE my_type (t1 text, t2 int, t3 date);
Oder Wenn der Typ einer vorhandenen Tabelle übereinstimmt, können Sie einfach den Tabellennamen als zusammengesetzten Typ verwenden.
Oder wenn Sie den Typ nur vorübergehend benötigen , können Sie eine TEMPORARY TABLE erstellen , das einen temporären Typ für die Dauer Ihrer Sitzung registriert :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
Sie könnten dies sogar für eine einzelne Transaktion tun :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
Dann können Sie diese Abfrage verwenden:
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;
Oder auch nur (wie oben, einfacher, kürzer, vielleicht weniger leicht verständlich):
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>;
Der CASE Ausdruck wird auf diese Weise einmal für jede Spalte ausgewertet. Ist die Auswertung nicht trivial, ist die andere Variante mit Unterabfrage schneller.