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

Iterace přes záznamy PostgreSQL. Jak odkazovat na data z dalšího řádku?

Obecně si musíte nastudovat základy , než začnete klást otázky.
Přečtěte si vynikající příručku o CREATE FUNCTION , PL/pgSQL a funkce SQL .

Hlavní body, proč je příklad nesmysl

  • Za prvé, nemůžete odevzdat identifikátor jako ty. Identifikátory nelze parametrizovat v prostém SQL. Budete potřebovat dynamické SQL k tomu.
    Samozřejmě to podle vašich požadavků ve skutečnosti nepotřebujete. Jedná se pouze o jeden stůl. Je nesmysl zkoušet to parametrizovat.

  • Nepoužívejte názvy typů jako identifikátory. Používám _date místo date jako název parametru a přejmenoval sloupec tabulky na asset_date . ALTER odpovídající definici vaší tabulky.

  • Funkce načítající data z tabulky nemůže být nikdy IMMUTABLE . Přečtěte si příručku.

  • Mixujete syntaxi SQL s prvky plpgsql nesmyslnými způsoby. WITH je součástí SELECT a nelze je kombinovat s řídicími strukturami plpgsql jako LOOP nebo IF .

Správná funkce

Správná funkce může vypadat takto (jeden z mnoha způsobů):

CREATE FUNCTION percentage_change_func(_asset_symbol text)
  RETURNS TABLE(asset_date date, price numeric, pct_change numeric) AS
$func$
DECLARE
   last_price numeric;
BEGIN

FOR asset_date, price IN
   SELECT a.asset_date, a.price
   FROM   asset_histories a
   WHERE  a.asset_symbol = _asset_symbol 
   ORDER  BY a.asset_date  -- traverse ascending
LOOP
   pct_change := price / last_price; -- NULL if last_price is NULL
   RETURN NEXT;
   last_price := price;
END LOOP;

END
$func$ LANGUAGE plpgsql STABLE

Výkon by neměl být tak špatný, ale je to jen zbytečná komplikace.

Správné řešení:prostý dotaz

Nejjednodušší (a pravděpodobně nejrychlejší) způsob by byl s funkcí okna lag() :

SELECT asset_date, price
      ,price / lag(price) OVER (ORDER BY asset_date) AS pct_change
FROM   asset_histories
WHERE  asset_symbol = _asset_symbol 
ORDER  BY asset_date;

Standardní odchylka

Podle vašeho pozdějšího komentáře chcete vypočítat statistická čísla, jako je standardní odchylka.
Existují vyhrazené agregační funkce pro statistiky v PostgreSQL.



  1. Zachycování změn dat nebo sledování změn – stejné jako tradiční tabulka kontrolních záznamů?

  2. SELECT z tabulky se seznamem Varying IN v klauzuli WHERE

  3. Vysvětlení případu Oracle s tipy a příklady

  4. Jak spouštět uložené procedury s Doctrine2 a MySQL