遍历PostgreSQL记录。如何参考下一行数据?
技术问答
184 人阅读
|
0 人回复
|
2023-09-14
|
我是PostgreSQL新手,在这里写函数很难。所以我希望有人能帮助我知道该怎么办。
: V4 w% \& B3 P我有一个股票价格和日期表。我想计算每个项目与前一天相比的变化百分比。对于最早的数据,前一天没有记录,所以项目可以简单Nil。有人可以查看我的功能并为我提供它
! w. O- [- l6 o/ r' W6 v以下帮助:a)如何引用下一行的数据,以及- T2 J: |: w8 E$ Z& l
b)帮我清理数据?
8 {* p1 v: s- m! U2 C我知道该WITH声明可能不应该放在IF声明之上。但是从逻辑上讲,这是到目前为止我一直在思考的方式,因此也是我编写它的方式。如果您能建议应该如何看待它,也将不胜感激。
; Y0 q8 d, l$ u% X8 [' j- iCREATE FUNCTION percentage_change_func(asset_histories) RETURNS numeric LANGUAGE sql IMMUTABLE AS $func$DECLAREr asset_histories%rowtypeBEGIN WITH twodaysdata AS (SELECT date,price,asset_symbol FROM asset_histories WHERE asset_symbol = $1.asset_symbol AND asset_histories.date PostgreSQL 9.2。5 o* t3 v' G: a
; [* E/ A6 x U1 \/ _$ c 解决方案:
! e- z6 R' h8 W) ^0 p; ? 我想计算每个项目与前一天相比的变化百分比。
( q7 b G& T4 ?! {% y! h' `通常,你需要 学习基础知识 。
; X2 j; }0 c+ c4 M' k) x+ S优秀的手动约 阅读CREATEFUNCTION ,PL // Y1 N( A$ f: z6 M7 e
pgSQL的 和
$ ?3 |; L. x! ^7 a1 LSQL函数7 @8 M, z2 T9 u: O q l! r m' P- Z
。
$ L9 X/ t' y' Z( Q' v# l: o* _要点-为什么这个例子是胡说八道?首先,你不能像你一样上交 标识符 。不能普通SQL参数化标识符。为此,您需要 动态SQL 。1 r8 c6 V0 c" y& S( E+ v
当然,根据你的要求,你实际上不需要。只涉及一张桌子。试图参数化它是胡说八道。不要使用类型名称作为标识符。_date而不是date作为参数名称,重新命名您的列表asset_date。ALTER您的表定义相应。
, B) b5 o4 p( h& N" P6 X* n从表中获取数据的功能永远不可能IMMUTABLE。阅读手册。
* }. X/ p/ y; x% }, h$ Q/ J你以荒谬的方式将是荒谬的SQL语法与plpgsql元素混合在一起。WITH是SELECT句子的一部分不能与plpgsql控制结构(如LOOP或混合使用IF。6 c5 s( r: T; _$ s) ?& W
适当的功能适当的功能可能看起来像这样(多种方式之一):
& a& x j- w+ o3 r' S- uCREATE FUNCTION percentage_change_func(_asset_symbol text) RETURNS TABLE(asset_date date,price numeric,pct_change numeric) AS$func$DECLARE last_price numeric;BEGINFOR 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 ascendingLOOP pct_change := price / last_price; -- NULL if last_price is NULL RETURN NEXT; last_price := price;END LOOP;END$func$ LANGUAGE plpgsql STABLE性能不应该那么差,但这只是毫无意义的复杂性。' o; q; R- t7 I3 c0 E& z
正确的解决方案:简单查询最简单(可能最快)的方法是使用window函数7 d% l. Q. W9 I( C
lag() :, n2 G! j$ H, B: `( p! h u" t: _
SELECT asset_date,price price / lag(price) OVER (ORDER BY asset_date) AS pct_changeFROM asset_historiesWHERE asset_symbol = _asset_symbol ORDER BY asset_date;标准偏差根据你以后的评论,你想计算统计数字(比如标准差)。PostgreSQL中
$ Q' N+ [0 b6 O5 `% w& h有专用的; [$ n0 n5 ]" k7 U. G
统计采用聚合函数 。 |
|
|
|
|
|