sql >> Database teknologi >  >> RDS >> PostgreSQL

Returner rækker, der matcher elementer af input-array i plpgsql-funktionen

Dette virker:

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;

Ring til:

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

Eller (opdatering - eksempel med dollar-citering):

SELECT * FROM avg_purchases($x${foo,Bar,baz,"}weird_name'$$"}$x$);
  • Mere om, hvordan du citerer strenge bogstaver:
    Indsæt tekst med enkelte anførselstegn i PostgreSQL

  • Du behøver ikke dynamisk SQL her.

  • Mens du kan pak den ind i en plpgsql-funktion (som kan være nyttig), en simpel SQL-funktion klarer jobbet fint.

  • Du har typeuoverensstemmelser .

    • resultatet af avg() kan være numeric at holde et præcist resultat. Jeg caster til float8 for at få det til at fungere, hvilket blot er et alias for double precision (du kan bruge begge dele). Hvis du har brug for perfekt præcision, skal du bruge numeric i stedet.
    • Siden du GROUP BY last_name du vil have en almindelig text OUT parameter i stedet for text[] .

VARIADIC

Et array er en nyttig type input. Hvis det er nemmere for din klient, kan du også bruge en VARIADIC inputparameter, der gør det muligt at sende arrayet som en liste over elementer :

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;

Ring til:

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

Eller (med dollar-angivelse):

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

Vær opmærksom på, at standard Postgres kun tillader maksimalt 100 elementer . Dette bestemmes på kompileringstidspunktet af den forudindstillede mulighed:

max_function_args (integer)

Rapporterer det maksimale antal funktionsargumenter. Det bestemmes af værdien af ​​FUNC_MAX_ARGS når du bygger serveren. Standardværdien er 100 argumenter.

Du kan stadig kalde det med array-notation, når det er præfikset med nøgleordet VARIADIC :

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

For større arrays (100+), ville jeg også bruge unnest() i en underforespørgsel og JOIN til det, som har en tendens til at skalere bedre:

  • Optimering af en Postgres-forespørgsel med et stort IN



  1. Eksempel på JDBC-erklæring – Batch-indsæt, opdatering, slet

  2. Ren måde at bruge postgresql vinduesfunktioner i django ORM?

  3. Oprettelse af tabelnavne, der er reserverede ord/søgeord i MS SQL Server

  4. Basering af databasemodeller i virkeligheden:En bloggers udfordring