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

Vlastní agregát PostgreSQL pro kruhový průměr

Můžete použít POLE zadejte interně. Typ argumentu může být stále libovolný číselný typ. Demonstrace pomocí float (=double precision ):

CREATE OR REPLACE FUNCTION f_circavg (float[], float)
  RETURNS float[] LANGUAGE sql STRICT AS
'SELECT ARRAY[$1[1] + sin($2), $1[2] + cos($2), 1]';

CREATE OR REPLACE FUNCTION f_circavg_final (float[])
  RETURNS float  LANGUAGE sql AS
'SELECT CASE WHEN $1[3] > 0 THEN atan2($1[1], $1[2]) END';

CREATE AGGREGATE circavg (float) (
   sfunc     = f_circavg
 , stype     = float[]
 , finalfunc = f_circavg_final
 , initcond  = '{0,0,0}'
);

Přechodová funkce f_circavg() je definováno STRICT , takže ignoruje řádky s NULL vstup. Nastavuje také třetí prvek pole pro identifikaci sad s jedním nebo více vstupními řádky – jinak CASE konečná funkce vrací NULL .

Dočasná tabulka pro testování:

CREATE TEMP TABLE t (x float);
INSERT INTO t VALUES (2), (NULL), (3), (4), (5);

Vložil jsem NULL hodnotu také otestovat STRICT kouzlo. Volejte:

SELECT circavg(x) FROM t;

       circavg
-------------------
 -2.78318530717959

Křížová kontrola:

SELECT atan2(sum(sin(x)), sum(cos(x))) FROM t;

       atan2
-------------------
 -2.78318530717959

Vrací totéž. Zdá se, že to funguje. V testu s větší tabulkou byl poslední výraz s běžnými agregačními funkcemi 4x rychlejší než vlastní agregace.

Test pro nulové vstupní řádky / pouze NULL vstup:

SELECT circavg(x) FROM t WHERE false;     -- no input rows
SELECT circavg(x) FROM t WHERE x IS NULL; -- only NULL input

Vrátí NULL v obou případech.



  1. Aktualizujte všechny řádky v databázi pomocí hodnoty hash

  2. Použití aliasů sloupců v poli Mřížka prodejní objednávky

  3. Laravel 5:zkontrolujte, zda uživatel patří do seznamu moderátorů, než mu povolíte úpravy

  4. Jak se připojit a extrahovat v SQL