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

Iteration gennem PostgreSQL-poster. Hvordan henvises til data fra næste række?

Generelt skal du studere det grundlæggende , før du begynder at stille spørgsmål.
Læs den fremragende manual om CREATE FUNCTION , PL/pgSQL og SQL-funktioner .

Vigtige punkter, hvorfor eksemplet er nonsens

  • For det første kan du ikke aflevere en identifikator ligesom du gør. Identifikatorer kan ikke parametreres i almindelig SQL. Du skal bruge dynamisk SQL for det.
    Selvfølgelig har du faktisk ikke brug for det, i henhold til dine krav. Der er kun ét bord involveret. Det er noget nonsens at forsøge at parametrere det.

  • Brug ikke typenavne som identifikatorer. Jeg bruger _date i stedet for date som parameternavn og omdøbte din tabelkolonne til asset_date . ALTER din tabeldefinition i overensstemmelse hermed.

  • En funktion, der henter data fra en tabel, kan aldrig være IMMUTABLE . Læs manualen.

  • Du blander SQL-syntaks med plpgsql-elementer på meningsløse måder. WITH er en del af en SELECT sætning og kan ikke blandes med plpgsql kontrolstrukturer som LOOP eller IF .

Korrekt funktion

En korrekt funktion kunne se sådan ud (en af ​​mange måder):

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

Ydeevnen burde ikke være så dårlig, men det er bare en meningsløs komplikation.

Korrekt løsning:almindelig forespørgsel

Den enkleste (og sandsynligvis hurtigste) måde ville være med vinduesfunktionen 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;

Standardafvigelse

Som i din senere kommentar vil du beregne statistiske tal som standardafvigelse.
Der er dedikerede aggregerede funktioner til statistik i PostgreSQL.



  1. Upload af et Excel-ark og import af data til SQL Server-database

  2. Skinner omfang for IS NOT NULL og er ikke tomt/tomt?

  3. Konverter UUID til/fra binær i Node

  4. Mysql mange til mange forhold forespørgsel. Hvordan får man alle tags af filtrerede indlæg?