PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Iteracja przez rekordy PostgreSQL. Jak odwołać się do danych z następnego wiersza?

Zasadniczo musisz poznać podstawy , zanim zaczniesz zadawać pytania.
Przeczytaj doskonałą instrukcję o CREATE FUNCTION , PL/pgSQL i funkcje SQL .

Główne punkty, dlaczego przykład jest nonsensem

  • Po pierwsze, nie możesz oddać identyfikatora tak jak ty. Nie można sparametryzować identyfikatorów w zwykłym języku SQL. Potrzebujesz dynamiczny SQL w tym celu.
    Oczywiście tak naprawdę nie jest to potrzebne, zgodnie z Twoimi wymaganiami. W grę wchodzi tylko jeden stół. Nie ma sensu próbować go sparametryzować.

  • Nie używaj nazw typów jako identyfikatorów. Używam _date zamiast date jako nazwę parametru i zmieniono nazwę kolumny tabeli na asset_date . ALTER zgodnie z definicją tabeli.

  • Funkcja pobierająca dane z tabeli nigdy nie może być IMMUTABLE . Przeczytaj instrukcję.

  • Mieszasz składnię SQL z elementami plpgsql w bezsensowny sposób. WITH jest częścią SELECT instrukcja i nie może być mieszana ze strukturami kontrolnymi plpgsql, takimi jak LOOP lub IF .

Właściwe działanie

Właściwa funkcja może wyglądać tak (jeden z wielu sposobów):

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

Wydajność nie powinna być taka zła, ale to tylko bezsensowna komplikacja.

Właściwe rozwiązanie:zwykłe zapytanie

Najprostszym (i prawdopodobnie najszybszym) sposobem byłoby użycie funkcji 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;

Odchylenie standardowe

Zgodnie z Twoim późniejszym komentarzem, chcesz obliczyć liczby statystyczne, takie jak odchylenie standardowe.
Istnieją dedykowane funkcje agregujące dla statystyk w PostgreSQL.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL nie używa częściowego indeksu

  2. Połącz wiele wierszy w tablicy za pomocą SQL na PostgreSQL

  3. Pobieranie elementów json o określonej nazwie klucza ze złożonej struktury zagnieżdżonej w postgres

  4. Co sądzisz o bazach danych Postgres i Firebird?

  5. Zmienić ręcznie plan wykonania zapytania w postgresql?