PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Menggunakan CASE di PostgreSQL untuk memengaruhi beberapa kolom sekaligus

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sierra Tinggi + Python + Kesalahan Postgresql:Instruksi ilegal:4

  2. Kustom ORDER BY Penjelasan

  3. Pengumpulan aneh dengan postgresql

  4. masalah dengan python manage.py migrasi -> Tidak ada modul bernama psycopg2

  5. Menghubungkan PostgreSQL dengan R