Postgres根据客户

时间:2019-08-11 23:35:53

标签: sql postgresql amazon-web-services

我已经将应用程序部署到了Heroku和AWS Beanstalk。他们都使用此SQL查询来查询同一个Postgres数据库实例(在AWS RDS中),如下所示,以查询过去16天(包括今天)的计数

SELECT
    d.date AS interval,
    count(ct.id) AS count
FROM (SELECT
        to_char(date_trunc('day', (CURRENT_DATE - offs)), 'YYYY-MM-DD') AS date
      FROM generate_series(0, 15) AS offs) d
   LEFT OUTER JOIN my_table ct ON d.date = to_char(date_trunc('day', ct.created_at::timestamp WITH time zone at time zone 'US/Eastern'),    'YYYY-MM-DD')
WHERE
    ct.inserted_at::bigint >= 1564200000000.0
GROUP BY
    d.date;

WHERE子句中的纪元以毫秒为单位,以编程方式推导为美国东部时区15天前的午夜。我已经检查了在AWS Beanstalk和Heroku上发出查询时该值是否相同,因此这里不应该考虑这个因素。

Heroku应用程序按预期提供了16行,就好像我从本地计算机查询一样。但是,AWS Beantalk服务器返回了15行,而没有今天的数据点。我觉得这一定与时区有关。我是Postgres的新手,并通过Google搜索获得了此查询。 CURRENT_DATE在不同的计算机上是否不同,从而导致此问题? SQL大师请在这里帮助我,谢谢!!

1 个答案:

答案 0 :(得分:1)

CURRENT_DATE取决于会话的时区。如果未在会话级别设置,则默认为用户的默认时区,然后是数据库的默认时区,然后是集群的默认值。

一个例子:

postgres=# set time zone 'UTC';
SET
postgres=# select current_date;
 current_date
--------------
 2019-08-12
(1 row)
postgres=# set time zone 'Australia/ACT';
SET
postgres=# select current_date;
 current_date
--------------
 2019-08-13
(1 row)

此外,根据ct.created_at的数据类型,这也可能会受到会话时区的影响。这是一个示例:

-- A simple table with two columns, one w/o time zone and one with
postgres=# create table test (a timestamp, b timestamptz);
CREATE TABLE
postgres=# set timezone to 'UTC';
SET
postgres=# insert into test values (now(), now());
INSERT 0 1
postgres=# insert into test values (now(), now());
INSERT 0 1
postgres=# insert into test values (now(), now());
INSERT 0 1
postgres=# select a::timestamp with time zone at time zone 'US/Eastern', b::timestamp with time zone at time zone 'US/Eastern' from test;
          timezone          |          timezone
----------------------------+----------------------------
 2019-08-12 10:39:31.043397 | 2019-08-12 10:39:31.043397
 2019-08-12 10:39:32.57214  | 2019-08-12 10:39:32.57214
 2019-08-12 10:39:33.258001 | 2019-08-12 10:39:33.258001
(3 rows)

-- When the session time zone is set to UTC, these are the same
-- What happens when we change?

postgres=# set time zone 'US/Eastern';
SET
postgres=# select a::timestamp with time zone at time zone 'US/Eastern', b::timestamp with time zone at time zone 'US/Eastern' from test;
          timezone          |          timezone
----------------------------+----------------------------
 2019-08-12 14:39:31.043397 | 2019-08-12 10:39:31.043397
 2019-08-12 14:39:32.57214  | 2019-08-12 10:39:32.57214
 2019-08-12 14:39:33.258001 | 2019-08-12 10:39:33.258001
(3 rows)

“无时区的时间戳记”现在与其他时间间隔不同了四个小时。

因此,如果您在输出中遇到差异,可能值得在脚本中添加show time zone;语句以查看是否存在差异。