1. SQL padrão:LEFT JOIN
uma única linha de valores
Você pode
LEFT JOIN
uma linha de valores usando a condição (avaliando-a assim uma vez). Em seguida, você pode adicionar valores de fallback por coluna com COALESCE()
. Essa variante de sintaxe é mais curta e um pouco mais rápida com vários valores - especialmente interessante para uma condição cara/longa:
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;
Como a tabela derivada
x
consiste em um único linha, juntar sem mais condições está bem. Lançamentos de tipo explícito são necessários na subconsulta. Eu uso
text
no exemplo (que é o padrão para literais de string de qualquer maneira). Use seus tipos de dados reais. O atalho de sintaxe value::type
é específico do Postgres, use cast(value AS type)
para SQL padrão. Se a condição não for
TRUE
, todos os valores em x
são NULL e COALESCE
entra em ação. Ou , já que todos os valores candidatos vêm da tabela
rtd2
no seu caso particular, LEFT JOIN
para rtd2
usando o CASE
original condição e CROSS JOIN
para uma linha com valores padrão: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;
Depende das condições de junção e do restante da consulta.
2. Específico do PostgreSQL
2a. Expandir uma matriz
Se suas várias colunas compartilharem o mesmo tipo de dados , você pode usar uma matriz em uma subconsulta e expandi-la no
SELECT
externo :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;
Fica mais complicado se as colunas não compartilharem o mesmo tipo de dados. Você pode convertê-los todos para
text
(e opcionalmente converter de volta no SELECT
externo ), ou você pode ... 2b. Decompor um tipo de linha
Você pode usar um tipo composto personalizado (tipo de linha) para armazenar valores de vários tipos e simplesmente *-expandê-lo no
SELECT
externo . Digamos que temos três colunas:text
, integer
e date
. Para repetidos use, crie um tipo composto personalizado:CREATE TYPE my_type (t1 text, t2 int, t3 date);
Ou se o tipo de uma tabela existente corresponder, você pode simplesmente usar o nome da tabela como tipo composto.
Ou se você precisar apenas do tipo temporariamente , você pode criar uma
TEMPORARY TABLE
, que registra um tipo temporário para a duração de sua sessão :CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
Você pode até fazer isso para uma transação única :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
Então você pode usar esta consulta:
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 mesmo apenas (o mesmo que acima, mais simples, mais curto, talvez menos fácil de entender):
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>;
O
CASE
expressão é avaliada uma vez para cada coluna desta forma. Se a avaliação não for trivial, a outra variante com uma subconsulta será mais rápida.