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.