Umumnya Anda perlu mempelajari dasar-dasarnya , sebelum Anda mulai mengajukan pertanyaan.
Baca manual yang bagus tentang CREATE FUNCTION
, PL/pgSQL
dan fungsi SQL
.
Poin utama mengapa contoh ini tidak masuk akal
-
Pertama, Anda tidak dapat menyerahkan pengidentifikasi seperti yang Anda lakukan. Pengidentifikasi tidak dapat diparameterisasi dalam SQL biasa. Anda memerlukan SQL dinamis untuk itu.
Tentu saja, Anda sebenarnya tidak membutuhkan itu, sesuai dengan kebutuhan Anda. Hanya ada satu meja yang terlibat. Tidak masuk akal untuk mencoba dan membuat parameter. -
Jangan gunakan nama tipe sebagai pengidentifikasi. Saya menggunakan
_date
bukannyadate
sebagai nama parameter dan ganti nama kolom tabel Anda menjadiasset_date
.ALTER
definisi tabel Anda sesuai. -
Fungsi yang mengambil data dari tabel tidak akan pernah bisa
IMMUTABLE
. Baca manualnya. -
Anda mencampur sintaks SQL dengan elemen plpgsql dengan cara yang tidak masuk akal.
WITH
adalah bagian dariSELECT
pernyataan dan tidak dapat dicampur dengan struktur kontrol plpgsql sepertiLOOP
atauIF
.
Fungsi yang tepat
Fungsi yang tepat dapat terlihat seperti ini (salah satu dari banyak cara):
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
Performanya seharusnya tidak terlalu buruk, tapi itu hanya komplikasi yang sia-sia.
Solusi yang tepat:kueri biasa
Cara paling sederhana (dan mungkin tercepat) adalah dengan fungsi jendela 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;
Standar deviasi
Sesuai komentar Anda nanti, Anda ingin menghitung angka statistik seperti simpangan baku.
Ada fungsi gabungan untuk statistik
di PostgreSQL.