1. SQL estándar:LEFT JOIN
una sola fila de valores
Podrías LEFT JOIN
una fila de valores usando la condición (evaluándola así una vez). Luego puede agregar valores alternativos por columna con COALESCE()
.
Esta variante de sintaxis es más corta y un poco más rápida con múltiples valores, especialmente interesante para una condición costosa/larga:
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;
Dado que la tabla derivada x
consiste en un simple fila, unirse sin más condiciones está bien.
Conversiones de tipos explícitos son necesarios en la subconsulta. Yo uso text
en el ejemplo (que es el valor predeterminado para los literales de cadena de todos modos). Utilice sus tipos de datos reales. El atajo de sintaxis value::type
es específico de Postgres, use cast(value AS type)
para SQL estándar.
Si la condición no es TRUE
, todos los valores en x
son NULL y COALESCE
entra en acción.
O , ya que todos los valores candidatos provienen de la tabla rtd2
en su caso particular, LEFT JOIN
a rtd2
usando el CASE
original condición y CROSS JOIN
a una fila con valores predeterminados:
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 de las condiciones de unión y del resto de la consulta.
2. Específico de PostgreSQL
2a. Expandir una matriz
Si sus diversas columnas comparten el mismo tipo de datos , puede usar una matriz en una subconsulta y expandirla en el 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;
Se vuelve más complicado si las columnas no comparten el mismo tipo de datos. Puedes convertirlos todos en text
(y, opcionalmente, volver a convertir en el exterior SELECT
), o puede...
2b. Descomponer un tipo de fila
Puede usar un tipo compuesto personalizado (tipo de fila) para contener valores de varios tipos y simplemente *-expándalo en el exterior SELECT
. Digamos que tenemos tres columnas:text
, integer
y date
. Para repetidas use, cree un tipo compuesto personalizado:
CREATE TYPE my_type (t1 text, t2 int, t3 date);
O si el tipo de una tabla existente coincide, puede usar el nombre de la tabla como tipo compuesto.
O si solo necesita el tipo temporalmente , puede crear una TEMPORARY TABLE
, que registra un tipo temporal durante la duración de su sesión :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
Incluso podría hacer esto para una transacción única :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
Entonces puedes 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;
O simplemente (igual que arriba, más simple, más corto, tal vez 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>;
El CASE
expresión se evalúa una vez para cada columna de esta manera. Si la evaluación no es trivial, la otra variante con una subconsulta será más rápida.