sql - 如何将天数传递给 Postgres 函数?
问题描述
days
函数中的参数getAvgByDay()
不起作用,我猜是因为它在引号内:
CREATE OR REPLACE FUNCTION getAvgByDay(days int)
RETURNS TABLE ( average text,
date timestamp with time zone
) AS
$func$
BEGIN
RETURN QUERY
SELECT to_char( AVG(measure), '99999D22') AS average, ( now() - interval '$1 day') AS date
FROM (
SELECT mes.date, mes.measure
FROM measures mes
WHERE mes.date < ( now() - interval '$1 day')
) AS mydata;
END
$func$
LANGUAGE plpgsql;
解决方案
假设该列measures.date
实际上是数据类型timestamptz
而不是date
:
CREATE OR REPLACE FUNCTION get_avg_by_day(_days int)
RETURNS TABLE (average text, ts timestamptz) AS -- not using "date" for a timestamp
$func$
SELECT to_char(avg(measure), '99999D22') -- AS average
, now() - interval '1 day' * $1 -- AS ts
FROM measures m
WHERE m.date < now() - interval '1 day' * $1
$func$ LANGUAGE sql;
- 不需要PLpgSQL,可以是一个更简单的SQL函数。
- 不需要子查询。只会增加复杂性和成本而没有收获。
- 外部查询级别不需要列别名。那些没有被使用,因为可见的列名是在
RETURNS
子句中定义的。 - 不需要额外的括号。无论如何,运算符优先级都可以按需要工作。(在这种情况下也没有伤害。)
- 如果可以避免,请不要在 Postgres 中使用 CaMeL 案例标识符。
- 不要将
timestamptz
列称为“日期”。这是误导。改用“ts”。 最重要的是:您怀疑太多,并且“粘性位”已经解释过:字符串内没有插值。但只需将时间单位与您的输入相乘
integer
以减去给定的天数:interval '1 day' * $1
这比字符串连接更快更干净。
推荐阅读
- html - 右侧的响应图像
- c# - Unity3D - 如何在下拉菜单中更改 ItemLabel 的颜色
- text - 为什么文本在云控制台上打印不合适,但不是通过 SSH?
- api - 为条带订阅添加试用日期
- python - Django 和 AWS S3:存储和保护私有文件
- linux - tsv-summarize:找不到命令
- java - 在 Wicket 中的有效输入提交上,FeedbackPanel 显示的错误消息未清除
- sql - 将 SQL 表从长数据转换为宽数据
- android - activity_main.xml 中缺少类
- html - 如何在html css vue上为下拉选择制作网格视图选项?