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

Pisahkan string yang diberikan dan siapkan pernyataan kasus

Penyiapan bersih:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Gunakan istilah tunggal sebagai nama kolom untuk tunggal value.
Tipe datanya jelas date dan bukan timestamp .

Untuk mengubah parameter teks Anda menjadi tabel yang berguna:

SELECT unnest(string_to_array('2001-01-01to2001-01-05,2001-01-10to2001-01-15', ',')) AS date_range
     , unnest(string_to_array('s1,s2', ',')) AS set_name;

"Paralel unnest" berguna tetapi memiliki peringatan. Postgres 9.4 menambahkan solusi bersih, Postgres 10 akhirnya membersihkan perilaku ini. Lihat di bawah.

Eksekusi dinamis

Pernyataan yang disiapkan

Pernyataan yang disiapkan hanya dapat dilihat oleh sesi pembuatan dan mati bersamanya. Per dokumentasi:

Pernyataan yang disiapkan hanya bertahan selama sesi database saat ini.

PREPARE sekali per sesi :

PREPARE upd_tbl AS
UPDATE tbl t
SET    set_name = s.set_name
FROM  (
   SELECT unnest(string_to_array($1, ',')) AS date_range
        , unnest(string_to_array($2, ',')) AS set_name
   ) s
WHERE t.given_date BETWEEN split_part(date_range, 'to', 1)::date
                       AND split_part(date_range, 'to', 2)::date;

Atau gunakan alat yang disediakan oleh klien Anda untuk menyiapkan pernyataan.
Jalankan n kali dengan parameter arbitrer:

EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');

Fungsi sisi server

Fungsi dipertahankan dan terlihat oleh semua sesi.

CREATE FUNCTION sekali :

CREATE OR REPLACE FUNCTION f_upd_tbl(_date_ranges text, _names text)
  RETURNS void AS
$func$
UPDATE tbl t
SET    set_name = s.set_name
FROM  (
   SELECT unnest(string_to_array($1, ',')) AS date_range
        , unnest(string_to_array($2, ',')) AS set_name
   ) s
WHERE  t.given_date BETWEEN split_part(date_range, 'to', 1)::date
                        AND split_part(date_range, 'to', 2)::date
$func$  LANGUAGE sql;

Telepon n kali:

SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');

SQL Fiddle

Desain unggul

Gunakan parameter larik (masih dapat diberikan sebagai literal string), daterange ketik (keduanya hal 9.3) dan paralel baru unnest() (hal 9.4 ).

CREATE OR REPLACE FUNCTION f_upd_tbl(_dr daterange[], _n text[])
  RETURNS void AS
$func$
UPDATE tbl t
SET    set_name = s.set_name
FROM   unnest($1, $2) s(date_range, set_name)
WHERE  t.given_date <@ s.date_range
$func$  LANGUAGE sql;

<@ menjadi operator "elemen dikandung oleh".

Telepon:

SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
                  ,"[2001-01-20,2001-01-25]"}', '{s2,s5}');

Detail:

  • Hapus beberapa array secara paralel


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. CURRENT_TIMESTAMP dalam milidetik

  2. Cara menghasilkan pernyataan buat tabel sql untuk tabel yang ada di postgreSQL

  3. Apakah pesanan dalam subquery dijamin untuk dipertahankan?

  4. Nilai referensi kolom serial di kolom lain selama INSERT yang sama

  5. Optimalkan kueri GROUP BY untuk mengambil baris terbaru per pengguna