1. Standar-SQL:LEFT JOIN
satu baris nilai
Anda dapat LEFT JOIN
deretan nilai menggunakan kondisi (sehingga mengevaluasinya sekali). Kemudian Anda dapat menambahkan nilai fallback per kolom dengan COALESCE()
.
Varian sintaks ini lebih pendek dan sedikit lebih cepat dengan beberapa nilai - sangat menarik untuk kondisi mahal/panjang:
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;
Karena tabel turunan x
terdiri dari tunggal baris, bergabung tanpa syarat lebih lanjut tidak masalah.
Jenis pemeran eksplisit diperlukan dalam subquery. Saya menggunakan text
dalam contoh (yang merupakan default untuk string literal). Gunakan tipe data Anda yang sebenarnya. Pintasan sintaks value::type
khusus untuk Postgres, gunakan cast(value AS type)
untuk SQL standar.
Jika kondisi tidak TRUE
, semua nilai dalam x
adalah NULL, dan COALESCE
masuk.
Atau , karena semua nilai kandidat berasal dari tabel rtd2
dalam kasus khusus Anda, LEFT JOIN
ke rtd2
menggunakan CASE
asli kondisi dan CROSS JOIN
ke baris dengan nilai default:
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;
Itu tergantung pada kondisi bergabung dan sisa kueri.
2. Khusus PostgreSQL
2a. Luaskan larik
Jika berbagai kolom Anda memiliki tipe data yang sama , Anda dapat menggunakan larik dalam subkueri dan memperluasnya di SELECT
. luar :
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;
Ini menjadi lebih rumit jika kolom tidak memiliki tipe data yang sama. Anda dapat memasukkan semuanya ke text
(dan secara opsional mengonversi kembali di SELECT
luar) ), atau Anda dapat ...
2b. Dekomposisi jenis baris
Anda dapat menggunakan tipe komposit khusus (tipe baris) untuk menyimpan nilai dari berbagai tipe dan cukup *-perluas di SELECT
luar . Katakanlah kita memiliki tiga kolom:text
, integer
dan date
. Untuk berulang gunakan, buat jenis komposit khusus:
CREATE TYPE my_type (t1 text, t2 int, t3 date);
Atau jika tipe tabel yang ada cocok, Anda bisa menggunakan nama tabel sebagai tipe komposit.
Atau jika Anda hanya membutuhkan ketik sementara , Anda dapat membuat TEMPORARY TABLE
, yang mendaftarkan jenis sementara selama sesi your Anda :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);
Anda bahkan dapat melakukan ini untuk satu transaksi :
CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;
Kemudian Anda dapat menggunakan kueri ini:
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;
Atau malah hanya (sama seperti di atas, lebih sederhana, lebih pendek, mungkin kurang mudah dipahami):
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>;
CASE
ekspresi dievaluasi sekali untuk setiap kolom dengan cara ini. Jika evaluasinya tidak sepele, varian lain dengan subquery akan lebih cepat.