1. Standaard-SQL:LEFT JOIN
een enkele rij met waarden
Je zou kunnen LEFT JOIN
een rij waarden met behulp van de voorwaarde (waardoor deze één keer wordt geëvalueerd). Dan kun je fallback-waarden per kolom toevoegen met COALESCE()
.
Deze syntaxisvariant is korter en iets sneller met meerdere waarden - vooral interessant voor een dure / langdurige voorwaarde:
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;
Sinds de afgeleide tabel x
bestaat uit een enkele rij, meedoen zonder verdere voorwaarden is prima.
Expliciete typecasts zijn nodig in de subquery. Ik gebruik text
in het voorbeeld (wat sowieso de standaard is voor letterlijke tekenreeksen). Gebruik uw werkelijke gegevenstypen. De syntaxissneltoets value::type
is Postgres-specifiek, gebruik cast(value AS type)
voor standaard SQL.
Als de voorwaarde niet TRUE
is , alle waarden in x
zijn NULL en COALESCE
begint.
Of , aangezien alle kandidaatwaarden afkomstig zijn uit tabel rtd2
in uw specifieke geval, LEFT JOIN
naar rtd2
met behulp van de originele CASE
voorwaarde en CROSS JOIN
naar een rij met standaardwaarden:
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;
Het hangt af van de deelnamevoorwaarden en de rest van de zoekopdracht.
2. PostgreSQL-specifiek
2a. Een array uitbreiden
Als uw verschillende kolommen hetzelfde gegevenstype delen , kunt u een array in een subquery gebruiken en deze uitbreiden in de buitenste 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;
Het wordt ingewikkelder als de kolommen niet hetzelfde gegevenstype delen. Je kunt ze allemaal casten naar text
(en optioneel terug converteren in de buitenste SELECT
), of je kunt ...
2b. Een rijtype ontleden
U kunt een aangepast samengesteld type (rijtype) gebruiken om waarden van verschillende typen vast te houden en deze eenvoudig *-uit te breiden in de buitenste SELECT
. Stel dat we drie kolommen hebben:text
, integer
en date
. Voor herhaald gebruik, maak een aangepast composiettype:
CREATE TYPE my_type (t1 text, t2 int, t3 date);
Of als het type van een bestaande tabel overeenkomt, kunt u de tabelnaam gewoon als samengesteld type gebruiken.
Of als je het type slechts tijdelijk nodig hebt , kunt u een TEMPORARY TABLE
. maken , die een tijdelijk type registreert voor de duur van uw sessie :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
Je zou dit zelfs kunnen doen voor een enkele transactie :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
Dan kunt u deze zoekopdracht gebruiken:
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;
Of zelfs gewoon (hetzelfde als hierboven, eenvoudiger, korter, misschien minder gemakkelijk te begrijpen):
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>;
De CASE
expressie wordt op deze manier voor elke kolom eenmaal geëvalueerd. Als de evaluatie niet triviaal is, zal de andere variant met een subquery sneller zijn.