pgSql没有提取日期的所有数据

时间:2017-10-10 18:36:41

标签: sql postgresql

以下针对Postgres数据库的查询一些如何为日期留下几行:2017-10-01。我也添加了时区。有没有办法解决这个问题?

{{1}}

2 个答案:

答案 0 :(得分:0)

让我们简化为查询的这一部分:

>=

这是围绕p.start_timestamp AT TIME ZONE p.timezone运算符的条件表达式。它有一个左侧(to_date('2017-09-30','YYYY-MM-DD') + INTERVAL '2 day')和一个右侧:( to_date('2017-09-30','YYYY-MM-DD') + INTERVAL '2 day' ),每个都是单独评估的,因此可以为每个记录确定最终的条件结果(真/假)

  

Postgres数据库如何为日期留下几行:2017-10-01

再看一下表达式的右侧:

'2017-10-02'

减少到这个值:

INTERVAL

换句话说,您仅限于2017-10-01'之后的记录。你真的想要那个float: left;部分吗?你想减去两天而不是添加吗?

答案 1 :(得分:0)

让我们假设两件事:

  1. 您要问"为什么此查询会显示10月1日的几行,因为它只显示10月2日或之后的行"

  2. p.start_timestamp的类型为TIMESTAMP WITHOUT TIME ZONE(我觉得这样做是安全的,因为否则在查询的其他部分中对它进行双时区转换是没有意义的。)

  3. 你有这个WHERE子句:

    where p.start_timestamp AT TIME ZONE p.timezone >= to_date('2017-09-30','YYYY-MM-DD') +  INTERVAL '2 day'
    

    现在,查询的左侧是p.start_timestamp AT TIME ZONE p.timezone,它将评估为TIMESTAMP WITH TIME ZONE。但是,查询的右侧是to_date('2017-09-30','YYYY-MM-DD') + INTERVAL '2 day',其计算结果为TIMESTAMP WITHOUT TIMEZONE。

    每当将TIMESTAMP与TIMEZONE与TIMESTAMP与TIMEZONE进行比较时,结果将取决于psql会话中当前的TimeZone设置,因为TIMESTAMP-no-TZ将被评估为就像它在psql中一样时区。例如,美国/凤凰城的上午12:31。在10月2日上午11点31分可以在美国/洛杉矶,根据日期(BTW,你选择最差的时区作为默认时间,因为美国/菲尼克斯很奇怪)。这将导致您在10月1日看到记录,具体取决于p.timezone的值。

    你将这个问题复杂化了:

    select min(p.start_timestamp AT TIME ZONE p.timezone AT TIME ZONE 'America/Phoenix') as Date
    

    ...所以现在您将所有时间戳显示为美国/凤凰城的时间戳,无论他们最初在哪个时区,或者他们与之比较的时区。如果您的TimeZone设置为UTC,您将看到很多10月1日的记录,因为UTC的10月2日与美国/菲尼克斯的10月1日重叠,这取决于日期。

    我怀疑,在剩下的查询中,你想要的WHERE子句是:

    where ( p.start_timestamp AT TIME ZONE p.timezone ) 
           >= 
          ( to_date('2017-09-30','YYYY-MM-DD') +  INTERVAL '2 day' ) 
          AT TIME ZONE 'America/Phoenix'
          AND p.start_timestamp AT TIME ZONE p.timezone 
           <= 
          ( TIMESTAMP '2017-10-30' AT TIME ZONE 'America/Phoenix' )
    

    所有这些都是一个说明性的课程,说明为什么您应该将所有时间戳数据存储为TIMESTAMP WITH TIME ZONE,而不是您在此处所做的事情。只要您将时区存储在一个单独的字段中并且始终使用AT TIME ZONE,您就会继续打破查询。此外,对于所有这些投射时区,您在这些时间列上拥有的任何索引都不太可能被使用。