带循环的 PostgreSQL 函数
我不擅长 postgres 函数。你能帮我一下吗?
假设我有这个数据库:
name | round |position | val
-----------------------------------
A | 1 | 1 | 0.5
A | 1 | 2 | 3.4
A | 1 | 3 | 2.2
A | 1 | 4 | 3.8
A | 2 | 1 | 0.5
A | 2 | 2 | 32.3
A | 2 | 3 | 2.21
A | 2 | 4 | 0.8
我想编写一个 Postgres 函数,它可以从 position=1
循环到 position=4
并计算相应的值。我可以使用 psycopg2 在 python 中执行此操作:
import psycopg2
import psycopg2.extras
conn = psycopg2.connect("host='localhost' dbname='mydb' user='user' password='pass'")
CURSOR = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cmd = """SELECT name, round, position, val from mytable"""
CURSOR.execute(cmd)
rows = CURSOR.fetchall()
dict = {}
for row in rows:
indx = row['round']
try:
dict[indx] *= (1-row['val']/100)
except:
dict[indx] = (1-row['val']/100)
if row['position'] == 4:
if indx == 1:
result1 = dict[indx]
elif indx == 2:
result2 = dict[indx]
print result1, result2
如何直接在 Postgres 中执行相同的操作,以便它返回 (name, result1, result2)
更新:
@a_horse_with_no_name,预期值为:
result1 = (1 - 0.5/100) * (1 - 3.4/100) * (1 - 2.2/100) * (1 - 3.8/100) = 0.9043
result2 = (1 - 0.5/100) * (1 - 32.3/100) * (1 - 2.21/100) * (1 - 0.8/100) = 0.6535
I'm not good at postgres functions. Could you help me out?
Say, I have this db:
name | round |position | val
-----------------------------------
A | 1 | 1 | 0.5
A | 1 | 2 | 3.4
A | 1 | 3 | 2.2
A | 1 | 4 | 3.8
A | 2 | 1 | 0.5
A | 2 | 2 | 32.3
A | 2 | 3 | 2.21
A | 2 | 4 | 0.8
I want to write a Postgres function that can loop from position=1
to position=4
and calculate the corresponding value. I could do this in python with psycopg2:
import psycopg2
import psycopg2.extras
conn = psycopg2.connect("host='localhost' dbname='mydb' user='user' password='pass'")
CURSOR = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cmd = """SELECT name, round, position, val from mytable"""
CURSOR.execute(cmd)
rows = CURSOR.fetchall()
dict = {}
for row in rows:
indx = row['round']
try:
dict[indx] *= (1-row['val']/100)
except:
dict[indx] = (1-row['val']/100)
if row['position'] == 4:
if indx == 1:
result1 = dict[indx]
elif indx == 2:
result2 = dict[indx]
print result1, result2
How can I do the same thing directly in Postgres so that it returns a table of (name, result1, result2)
UPDATE:
@a_horse_with_no_name, the expected value would be:
result1 = (1 - 0.5/100) * (1 - 3.4/100) * (1 - 2.2/100) * (1 - 3.8/100) = 0.9043
result2 = (1 - 0.5/100) * (1 - 32.3/100) * (1 - 2.21/100) * (1 - 0.8/100) = 0.6535
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
@Glenn 为您提供了一个带有聚合函数的非常优雅的解决方案。但要回答您的问题, plpgsql 函数可能如下所示:
测试设置:
通用函数
调用:
结果:
根据问题
调用的特定函数:
结果:
@Glenn gave you a very elegant solution with an aggregate function. But to answer your question, a plpgsql function could look like this:
Test setup:
Generic function
Call:
Result:
Specific function as per question
Call:
Result:
我猜您正在寻找聚合的“产品”功能。您可以在 Postgresql 和 Oracle 中创建自己的聚合函数。
请参阅 Postgresql 文档中的“用户定义的聚合”。上面的例子是我借用的
此处。还有其他 stackoverflow 响应显示了其他方法做这个。
I guess you are looking for an aggregate "product" function. You can create your own aggregate functions in Postgresql and Oracle.
See "User-Defined Aggregates" in the Postgresql doc. The example above I borrowed from
here. There are other stackoverflow responses that show other methods to do this.