PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Разделете дадения низ и подгответе изявление за case

Чиста настройка:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Използвайте термин в единствено число като име на колона за единично стойност.
Типът данни очевидно е date а не timestamp .

За да трансформирате вашите текстови параметри в полезна таблица:

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;

„Parallel unnest“ е удобен, но има своите предупреждения. Postgres 9.4 добавя чисто решение, Postgres 10 в крайна сметка санкционира поведението на това. Вижте по-долу.

Динамично изпълнение

Подготвено изявление

Подготвените изявления са видими само за създаващата сесия и умират с нея. По документация:

Подготвените оператори са валидни само за продължителността на текущата сесия на базата данни.

PREPARE веднъж на сесия :

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;

Или използвайте инструменти, предоставени от вашия клиент, за да подготвите изявлението.
Изпълнете n пъти с произволни параметри:

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

Функция от страна на сървъра

Функциите се запазват и се виждат за всички сесии.

CREATE FUNCTION веднъж :

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;

Обадете се n пъти:

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

SQL Fiddle

Превъзходен дизайн

Използвайте параметри на масива (все още могат да бъдат предоставени като низови литерали), daterange тип (и двете стр. 9.3) и новия паралел unnest() (стр. 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;

<@ е операторът "елементът се съдържа от".

Обадете се:

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

Подробности:

  • Отвържете паралелно множество масиви


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Добавете поредния индикатор към дата в PostgreSQL

  2. Как да конфигурирате PostgreSQL Sharding с ClusterControl

  3. PHP не зарежда php_pgsql.dll в Windows

  4. 9.6 Най-страшният турнир

  5. Настройка и използване на pgmemcache