sql >> Databáze >  >> RDS >> PostgreSQL

Vrátí řádky odpovídající prvkům vstupního pole ve funkci plpgsql

Toto funguje:

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;

Volejte:

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

Nebo (aktualizace – příklad s uvedením dolaru):

SELECT * FROM avg_purchases($x${foo,Bar,baz,"}weird_name'$$"}$x$);
  • Více o tom, jak citovat řetězcové literály:
    Vložit text s jednoduchými uvozovkami v PostgreSQL

  • Zde nepotřebujete dynamické SQL.

  • Zatímco můžete zabalte to do funkce plpgsql (což může být užitečné), jednoduchá funkce SQL to dělá dobře.

  • Máte neshody typu .

    • výsledek avg() může být numeric udržet přesný výsledek. Odesílám do float8 aby to fungovalo, což je jen alias pro double precision (můžete použít obojí). Pokud potřebujete dokonalou přesnost, použijte numeric místo toho.
    • Vzhledem k tomu, že GROUP BY last_name chcete prostý text Parametr OUT namísto text[] .

VARIADIC

Pole je užitečný typ vstupu. Pokud je to pro vašeho klienta jednodušší, můžete také použít VARIADIC vstupní parametr, který umožňuje předat pole jako seznam prvků :

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;

Volejte:

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

Nebo (s dolarem):

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

Uvědomte si, že standardní Postgres povoluje pouze maximálně 100 prvků . To je určeno v době kompilace přednastavenou možností:

max_function_args (integer)

Hlásí maximální počet argumentů funkce. Je určena hodnotou FUNC_MAX_ARGS při stavbě serveru. Výchozí hodnota je 100 argumentů.

Stále jej můžete volat pomocí zápisu pole, když je předponou klíčové slovo VARIADIC :

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

Pro větší pole (100+) bych také použil unnest() v dílčím dotazu a JOIN k tomu, který má tendenci se lépe škálovat:

  • Optimalizace dotazu Postgres s velkým IN



  1. Nainstalovat mysql-python (Windows)

  2. Jak Now() funguje v PostgreSQL

  3. Konfigurace spojení mezi klientem a serverem Oracle 10g

  4. Jak používat GROUP BY ke zřetězení řetězců v SQL Server?