简体   繁体   English

如何将天数传递给Postgres函数?

[英]How to pass the number of days to a Postgres function?

Argument days in function getAvgByDay() doesn't work, I guess because it is inside quotes: 函数getAvgByDay()中的参数days不起作用,我猜是因为它在引号内:

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;

There's no interpolation in strings. 字符串中没有内插。 But you can concatenate strings and cast them to an interval. 但是您可以连接字符串并将其强制转换为一个间隔。 Try: 尝试:

... concat(days, ' day')::interval ...

Or you could use format() , that's probably a little closer to what you originally had: 或者,您可以使用format() ,它可能与您最初拥有的内容更接近:

... format('%s day', days)::interval ...

Assuming the column measures.date is actually data type timestamptz and not a date : 假设该列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;
  • No need for PLpgSQL, can be a simper SQL function. 不需要PLpgSQL,可以是一个简单的SQL函数。
  • No need for a subquery. 无需子查询。 Only adds complexity and cost for no gain. 只增加复杂性和成本,却没有收益。
  • No need for column aliases in the outer query level. 在外部查询级别不需要列别名。 Those are not used, as visible column names are defined in the RETURNS clause. 不使用那些,因为在RETURNS子句中定义了可见的列名。
  • No need for extra parentheses. 不需要多余的括号。 Operator precedence works as desired anyway. 无论如何, 运算符优先级可以按需工作。 (No harm in this case, either.) (在这种情况下也没有害处。)
  • Don't use CaMeL case identifier in Postgres if you can avoid it. 如果可以避免,请不要在Postgres中使用CaMeL大小写标识符。
  • Don't call a timestamptz column "date". 不要将timestamptz列称为“日期”。 That's misleading. 这是误导。 Using "ts" instead. 使用“ ts”代替。
  • Most importantly: You suspected as much, and "sticky bit" already explained: no interpolation inside strings. 最重要的是:您对此表示怀疑,并且已经解释了“粘滞位”:字符串内无插值。 But just multiply the time unit with your integer input to subtract the given number of days: 但是只需将时间单位乘以integer输入即可减去给定的天数:

     interval '1 day' * $1 

    That's faster and cleaner than string concatenation. 这比字符串连接更快,更干净。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM