PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Korzystanie z dynamicznego zapytania + typ danych zdefiniowany przez użytkownika w Postgres

Podstawowa UPDATE

Zastąp pierwsze zapytanie tym znacznie krótszym i bardziej wydajnym pojedynczym UPDATE polecenie:

UPDATE features
SET   (x1,x2,x3,x4,x5,x6, y)   
    = ((x1 - g.avg1) / g.range1
     , (x2 - g.avg2) / g.range2
 --  , (x3 - ...
     , (y  - g.avgy) / g.rangey)
FROM (
   SELECT avg(x1) AS avg1, max(x1) - min(x1) AS range1
        , avg(x2) AS avg2, max(x2) - min(x2) AS range2
     -- , avg(x3) ...
        , avg(y) AS avgy, max(y) - min(y) AS rangey
   FROM   features
   ) g;

O krótkiej UPDATE składnia:

Funkcja dynamiczna

Opierając się na prostszym zapytaniu, oto dynamiczna funkcja dla dowolnej liczby kolumn:

CREATE OR REPLACE FUNCTION scale_function_dyn()
  RETURNS void AS
$func$
DECLARE
   cols text;  -- list of target columns
   vals text;  -- list of values to insert
   aggs text;  -- column list for aggregate query
BEGIN
   SELECT INTO cols, vals, aggs
          string_agg(quote_ident(attname), ', ')
        , string_agg(format('(%I - g.%I) / g.%I'
                          , attname, 'avg_' || attname, 'range_' || attname), ', ')
        , string_agg(format('avg(%1$I) AS %2$I, max(%1$I) - min(%1$I) AS %3$I'
                          , attname, 'avg_' || attname, 'range_' || attname), ', ')
   FROM   pg_attribute
   WHERE  attrelid = 'features'::regclass
   AND    attname NOT IN ('n', 'x0')  -- exclude columns from update
   AND    NOT attisdropped            -- no dropped (dead) columns
   AND    attnum > 0;                 -- no system columns

   EXECUTE format('UPDATE features
                   SET   (%s) = (%s)
                   FROM  (SELECT %s FROM features) g'
                 , cols, vals, aggs);

END
$func$  LANGUAGE plpgsql;

Powiązana odpowiedź z dodatkowym wyjaśnieniem:

Skrzypce SQL.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tłumaczenia relacji nie istnieją po migracji do Rails 3.2.1

  2. PostgreSQL wyłącza więcej danych wyjściowych

  3. Robienie lewego sprzężenia ze sprzężeniami w starym stylu

  4. UnicodeDecodeError:kodek „ascii” nie może zdekodować bajtu 0x92 na pozycji 47:liczba porządkowa poza zakresem(128)

  5. Zwróć listę stref czasowych obsługiwanych przez PostgreSQL