我有以1分钟为增量存储在Postgres中的股票的OHLCV数据。
我正在尝试以5分钟为间隔重新采样数据。我已使用此answer生成以下SQL查询。
这是生成的SQL查询:
SELECT
avg('open') AS open,
avg('high') AS high,
avg('low') AS low,
avg('close') AS close,
avg('volume') AS volume,
avg('open_interest') AS open_interest,
to_timestamp(floor(EXTRACT(epoch FROM 'timestamp') / 300) * 300) AS interval_alias
WHERE 'symbol'='IRFC-N8' GROUP BY interval_alias
我收到此错误:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) function avg(unknown) is not unique
LINE 1: SELECT avg('open') AS open, avg('high') AS high, avg('low') ...
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
你能告诉我哪里出了问题吗?
编辑1 :为更好地呈现而格式化的代码。
编辑2 :根据以下答案,我需要在avg函数的参数周围使用双引号。我正在使用sqlalchemy生成表达式,并且正在创建单引号的字符串。这是生成平均查询的代码部分:
cols = list()
cols.append(func.avg(self.p.open).label(self.p.open))
cols.append(func.avg(self.p.high).label(self.p.high))
cols.append(func.avg(self.p.low).label(self.p.low))
cols.append(func.avg(self.p.close).label(self.p.close))
cols.append(func.avg(self.p.volume).label(self.p.volume))
cols.append(func.avg(self.p.openinterest).label(self.p.openinterest))
seconds = self._get_seconds()
cols.append(func.to_timestamp(func.floor(func.extract("epoch", "timestamp") / seconds) * seconds).label("interval_alias"))
SqlAlchemy应该更好地了解使用双引号,但是会生成单引号。
答案 0 :(得分:1)
您的错误是在您的'
调用中使用单引号"
而不是双引号AVG()
。单引号标记文本,但您要为平均值命名列。因此,您需要双引号或可以保留双引号(这两种变体都显示在数据库小提琴中)。
编辑(真正的问题):
看来self.p.columnname
仅给出了列的名称,而不是列本身。在SQLAlchemy上,对特定列的引用是table.c.columnname
,用于引用特定列。请使用p
代替c
。
注意:
如果平均所有数据,则可能会丢失重要的数据,即实际的最小值和最大值。您可能希望与其他功能聚合为MIN
或MAX
。也许WITHIN GROUP
函数可以为您提供帮助。
https://www.postgresql.org/docs/current/static/functions-aggregate.html
https://www.postgresql.org/docs/9.5/static/functions-aggregate.html#FUNCTIONS-ORDEREDSET-TABLE