sql - Postgres 根据客户端返回不同的结果

标签 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 的新手,通过谷歌搜索得到了这个查询。 CURRENT_DATE 在不同的机器上是否不同从而导致问题? SQL高手请帮帮我,在此先感谢!

最佳答案

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

一个例子:

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 的数据类型,这也会受到 session 时区的影响。这是一个例子:

-- 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; 语句以查看是否存在任何差异。

关于sql - Postgres 根据客户端返回不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57454364/

相关文章:

mysql - MySQL 中的条件表选择

mysql - SQL OR NOT EXISTS 不起作用

postgresql - 从 pg_settings 选择自定义设置

php - pg_query() : Query failed: ERROR: operator does not exist: integer ~~ unknown\n

Javascript S3 GET Bucket(列表对象)格式化?

ios - 从 Parse-Server 传输到 dynamoDB。有哪些可预见的障碍?

amazon-web-services - 不允许为 VPC 创建 EC2 实例

mysql - 使用 UNION 选择但限制每个子查询并接收不同的值

postgresql - junit.framework.ComparisonFailure : value but value is equal

php - MySQL 中的唯一标识符