我已经将应用程序部署到了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大师请在这里帮助我,谢谢!!
答案 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;
语句以查看是否存在差异。