1. Standard-SQL :LEFT JOIN
une seule ligne de valeurs
Vous pouvez LEFT JOIN
une ligne de valeurs utilisant la condition (l'évaluant ainsi une fois). Ensuite, vous pouvez ajouter des valeurs de secours par colonne avec COALESCE()
.
Cette variante de syntaxe est plus courte et légèrement plus rapide avec plusieurs valeurs - particulièrement intéressante pour une condition coûteuse/longue :
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;
Depuis la table dérivée x
se compose d'un simple ligne, rejoindre sans autres conditions est très bien.
Casts de type explicites sont nécessaires dans la sous-requête. J'utilise text
dans l'exemple (qui est de toute façon la valeur par défaut pour les littéraux de chaîne). Utilisez vos types de données réels. Le raccourci de syntaxe value::type
est spécifique à Postgres, utilisez cast(value AS type)
pour SQL standard.
Si la condition n'est pas TRUE
, toutes les valeurs dans x
sont NULL, et COALESCE
entre en jeu.
Ou , puisque toutes les valeurs candidates proviennent de la table rtd2
dans votre cas particulier, LEFT JOIN
à rtd2
en utilisant le CASE
d'origine condition et CROSS JOIN
à une ligne avec des valeurs par défaut :
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;
Cela dépend des conditions de jointure et du reste de la requête.
2. Spécifique à PostgreSQL
2a. Développer un tableau
Si vos différentes colonnes partagent le même type de données , vous pouvez utiliser un tableau dans une sous-requête et le développer dans le SELECT
externe :
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;
Cela devient plus compliqué si les colonnes ne partagent pas le même type de données. Vous pouvez soit tous les convertir en text
(et éventuellement reconvertir dans le SELECT
externe ), ou vous pouvez ...
2b. Décomposer un type de ligne
Vous pouvez utiliser un type composite personnalisé (type de ligne) pour contenir des valeurs de différents types et simplement *-développez-le dans le SELECT
externe . Supposons que nous ayons trois colonnes :text
, integer
et date
. Pour répété utilisez, créez un type composite personnalisé :
CREATE TYPE my_type (t1 text, t2 int, t3 date);
Ou si le type d'une table existante correspond, vous pouvez simplement utiliser le nom de la table comme type composite.
Ou si vous n'avez besoin que du type temporairement , vous pouvez créer une TEMPORARY TABLE
, qui enregistre un type temporaire pour la durée de votre session :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
Vous pouvez même le faire pour une transaction unique :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
Ensuite, vous pouvez utiliser cette requête :
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;
Ou même juste (comme ci-dessus, plus simple, plus court, peut-être moins facile à comprendre) :
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>;
Le CASE
expression est évaluée une fois pour chaque colonne de cette façon. Si l'évaluation n'est pas triviale, l'autre variante avec une sous-requête sera plus rapide.