sql >> Databasteknik >  >> RDS >> PostgreSQL

Itererar genom PostgreSQL-poster. Hur refererar man till data från nästa rad?

I allmänhet måste du studera grunderna , innan du börjar ställa frågor.
Läs den utmärkta manualen om CREATE FUNCTION , PL/pgSQL och SQL-funktioner .

Huvudpunkter varför exemplet är nonsens

  • För det första kan du inte lämna in en identifierare som du gör. Identifierare kan inte parametriseras i vanlig SQL. Du behöver dynamisk SQL för det.
    Naturligtvis behöver du faktiskt inte det, enligt dina krav. Det är bara ett bord inblandat. Det är nonsens att försöka parametrisera det.

  • Använd inte typnamn som identifierare. Jag använder _date istället för date som parameternamn och döpte om din tabellkolumn till asset_date . ALTER din tabelldefinition därefter.

  • En funktion som hämtar data från en tabell kan aldrig vara IMMUTABLE . Läs manualen.

  • Du blandar SQL-syntax med plpgsql-element på orimliga sätt. WITH är en del av en SELECT och kan inte blandas med plpgsql-kontrollstrukturer som LOOP eller IF .

Riktig funktion

En korrekt funktion kan se ut så här (ett av många sätt):

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

Prestanda borde inte vara så dåligt, men det är bara en meningslös komplikation.

Rätt lösning:vanlig fråga

Det enklaste (och förmodligen snabbaste) sättet skulle vara med fönsterfunktionen 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;

Standardavvikelse

Enligt din senare kommentar vill du beräkna statistiska siffror som standardavvikelse.
Det finns dedikerade aggregera funktioner för statistik i PostgreSQL.



  1. SQLAlchemy Bestäm om unik begränsning finns

  2. Row Goals, Del 4:Anti Join Anti Pattern

  3. Antal poster i DB PHP

  4. Initiering av en MySQL-databas distribuerad i en AWS EKS