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

Връщане на редове, съответстващи на елементи от входния масив във функцията plpgsql

Това работи:

CREATE OR REPLACE FUNCTION avg_purchases(last_names text[] = '{}')
  RETURNS TABLE(last_name text, avg_purchase_size float8) AS
$func$
   SELECT last_name, AVG(purchase_size)::float8
   FROM   purchases
   WHERE  last_name = ANY($1)
   GROUP  BY last_name
$func$  LANGUAGE sql;

Обадете се:

SELECT * FROM avg_purchases('{foo,Bar,baz,"}weird_name''$$"}');

Или (актуализация - пример с цитиране на долари):

SELECT * FROM avg_purchases($x${foo,Bar,baz,"}weird_name'$$"}$x$);
  • Повече за това как да цитирате низови литерали:
    Вмъкнете текст с единични кавички в PostgreSQL

  • Тук нямате нужда от динамичен SQL.

  • Докато вие можете увийте го във функция plpgsql (която може да е полезна), простата SQL функция върши работата добре.

  • Имате несъответствия на типовете .

    • резултатът от avg() може да бъде numeric за да има точен резултат. Прехвърлям към float8 за да работи, което е просто псевдоним за double precision (можете да използвате и двете). Ако имате нужда от перфектна прецизност, използвайте numeric вместо това.
    • Тъй като GROUP BY last_name искате обикновен text OUT параметър вместо text[] .

VARIADIC

Масивът е полезен тип вход. Ако е по-лесно за вашия клиент, можете да използвате и VARIADIC входен параметър, който позволява да се предаде масивът като списък с елементи :

CREATE OR REPLACE FUNCTION avg_purchases(VARIADIC last_names text[] = '{}')
  RETURNS TABLE(last_name text, avg_purchase_size float8) AS
$func$
   SELECT last_name, AVG(purchase_size)::float8
   FROM   purchases
   JOIN  (SELECT unnest($1)) t(last_name) USING (last_name)
   GROUP  BY last_name
$func$  LANGUAGE sql;

Обадете се:

SELECT * FROM avg_purchases('foo', 'Bar', 'baz', '"}weird_name''$$"}');

Или (с цитиране на долари):

SELECT * FROM avg_purchases('foo', 'Bar', 'baz', $y$'"}weird_name'$$"}$y$);

Имайте предвид, че стандартният Postgres позволява само максимум 100 елемента . Това се определя по време на компилиране от предварително зададената опция:

max_function_args (integer)

Отчита максималния брой аргументи на функцията. Определя се от стойността на FUNC_MAX_ARGS при изграждане на сървъра. Стойността по подразбиране е 100 аргумента.

Все още можете да го извикате с нотация на масив, когато има префикс с ключовата дума VARIADIC :

SELECT * FROM avg_purchases(VARIADIC '{1,2,3, ... 99,100,101}');

За по-големи масиви (100+) бих използвал и unnest() в подзаявка и JOIN към него, което има тенденция да се мащабира по-добре:

  • Оптимизиране на заявка в Postgres с голям IN



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Намерете редове с множество дублиращи се полета с Active Record, Rails &Postgres

  2. Как pg_sleep_until() работи в PostgreSQL

  3. INITCAP() – Преобразуване в начални главни букви в PostgreSQL

  4. Как да коригирам грешките при несъответствие на версията pg_dump?

  5. съединете две различни таблици и премахнете дублирани записи