sql >> Database >  >> RDS >> PostgreSQL

Splits de gegeven string en bereid de case-instructie voor

Schone installatie:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Gebruik een enkelvoudige term als kolomnaam voor een enkele waarde.
Het gegevenstype is duidelijk date en niet een timestamp .

Om uw tekstparameters om te zetten in een bruikbare tabel:

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" is handig, maar heeft zijn kanttekeningen. Postgres 9,4 voegt een schone oplossing toe, Postgres 10 uiteindelijk ontsmet het gedrag hiervan. Zie hieronder.

Dynamische uitvoering

Voorbereide verklaring

Voorbereide uitspraken zijn alleen zichtbaar voor de creatiesessie en sterven ermee. Per documentatie:

Voorbereide instructies zijn alleen geldig voor de duur van de huidige databasesessie.

PREPARE eenmaal per sessie :

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;

Of gebruik de tools van uw klant om de verklaring voor te bereiden.
Voer n keer uit met willekeurige parameters:

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

Server-side functie

Functies blijven behouden en zijn zichtbaar voor allen sessies.

CREATE FUNCTION eenmaal :

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;

Bel n keer:

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

SQL Fiddle

Superieur ontwerp

Gebruik arrayparameters (kunnen nog steeds worden opgegeven als letterlijke tekenreeksen), een daterange type (beide pg 9.3) en de nieuwe parallelle unnest() (pag 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;

<@ zijnde de "element is bevat door" operator.

Bel:

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

Details:

  • Meerdere arrays parallel verwijderen


  1. Hoe krijg ik het eerste record in elke groep in MySQL

  2. Correct gebruik van transacties in SQL Server

  3. Hoe u de huidige tijd kunt krijgen (zonder tijdzone) in PostgreSQL

  4. Pivot-operator in SQL begrijpen