在Postgres中使用间隔中的可变周期

时间:2011-10-17 16:24:44

标签: postgresql variables intervals period

我有一个维护月度历史数据的关系。此数据将在每月的最后一天添加到表中。然后可以调用我正在编写的服务,指定一个月前和几个月之前检索历史数据。我这样做是通过创建startDate和endDate变量,然后在两者之间返回数据。我遇到的问题是startDate是endDate之前的可变数月,我无法弄清楚如何在一个区间内使用变量句点。

这就是我所拥有的:

    DECLARE
      endDate   TIMESTAMP := (DATE_TRUNC('MONTH',$2) + INTERVAL '1 MONTH') - INTERVAL '1 DAY';
      startDate TIMESTAMP := endDate - INTERVAL $3 'MONTH';

我知道startDate的行不正确。这怎么做得好?

3 个答案:

答案 0 :(得分:75)

使用此行:

startDate TIMESTAMP := endDate - ($3 || ' MONTH')::INTERVAL;

并注意MONTH之前的空格。 基本上:您构造一个类似4 MONTH的字符串,并将其与::type一起投射到适当的间隔。

修改:我找到了另一种解决方案:您可以使用interval计算:

startDate TIMESTAMP := endDate - $3 * INTERVAL '1 MONTH';

这对我来说有点好看。

答案 1 :(得分:6)

此代码与您的情况没有任何直接关系,但它确实说明了如何在INTERVAL算法中使用变量。我的桌子名称是“日历”。

CREATE OR REPLACE FUNCTION test_param(num_months integer)
  RETURNS SETOF calendar AS
$BODY$

    select * from calendar
    where cal_date <= '2008-12-31 00:00:00'
    and cal_date > date '2008-12-31' - ($1 || ' month')::interval;

$BODY$
  LANGUAGE sql VOLATILE
  COST 100
  ROWS 1000;

答案 2 :(得分:0)

我发现将可变时间段传递给 Postgres 的最易读的方法类似于 A.H. 的答案:乘以一个整数。但这可以在没有演员的情况下完成。

Python 示例(使用 sqlalchemypandas):

import pandas as pd
import sqlalchemy as sa

connection = sa.create_engine(connection_string)

df = pd.read_sql(
   sa.text('''
       select * from events
       where
       event_date between now() - (interval '1 day' * :ndays) and now()
       limit 100;
'''),
   connection,
   params={'ndays': 100}
)

天数 (ndays) 在 Python 中作为整数传递 - 因此不太可能出现意外后果。