PostgreSQL BETWEEN运算符的行为不同

时间:2019-06-12 11:03:10

标签: sql postgresql between

我正在使用sql查询来提取已部署解决方案的几天数据

我以以下方式使用查询

select column1, column2, column3, column 4 
where <condition 1> AND <condition 2> AND 
      created_timestamp BETWEEN '05-31-2019' AND '06-11-2019'

现在,它曾经用于获取所有列的值,并按预期的条件过滤数据,只是这里有一个扭曲。它没有获取作为上限的6月11日的数据。

据我所知,运算符之间包括所提供范围的两个端点。

更让我感到困惑的是,莫名其妙地包括了5月31日(sup)的数据(上限)。

  1. 我需要知道运算符之间是否包含范围的端点(尤其是在postgresql中,因此仅想确认它是否会发生变化)?

  2. 即使它包含/排除了两个端点的行为,我也不了解任何有此线索的偏见行为?

4 个答案:

答案 0 :(得分:4)

尝试使用正确的日期文字:

SELECT column1, column2, column3, column4
FROM your_table
WHERE created_timestamp BETWEEN '2019-05-31' AND '2019-06-11';

2019-05-31为ISO 8601格式,明确表示2019年5月31日为任何模式。

您可能会了解有关日期/时间类型here的规则的更多信息。

编辑:

之所以没有显示6月11日的数据,是因为使用2011-06-11作为范围的上限与使用2011-06-11 00:00:00相同。也就是说,它仅包括正好在午夜的6月11日。为了缓解这种情况,请使用6月12日作为上限:

SELECT column1, column2, column3, column4
FROM your_table
WHERE created_timestamp >= '2019-05-31' AND created_timestamp < '2019-06-12';

答案 1 :(得分:1)

如果created_timestamp是日期/时间值,而不只是日期,那么6月11日午夜(00:00小时)之后的所有内容都将不在BETWEEN中。所以你可以这样做

date_trunc('day', created_timestamp) BETWEEN '2019-05-31' AND '2019-06-11'

如前所述,日期应为yyyy-mm-dd格式。正如戈登提到的那样,在这种情况下不需要强制转换日期,但是他是对的,在某些情况下,您确实需要强制转换日期,这样做没有什么害处。

答案 2 :(得分:1)

我假设created_timestamptimestamp(带或不带时区)。

您使用的文字06-11-2019对应于该日期的午夜:

SELECT '06-11-2019'::timestamp with time zone;
      timestamptz       
------------------------
 2019-06-11 00:00:00+02
(1 row)

因此,结果不包含6月11日的数据也就不足为奇了。

有两种前进方式:

  1. 使用第二天和<运算符:

    ... WHERE created_timestamp >= '05-31-2019' AND created_timestamp < '06-12-2019'
    
  2. 将时间戳转换为date

    ... WHERE date(created_timestamp) BETWEEN '05-31-2019' AND '06-11-2019'
    

第二个选项不能在created_timestamp上使用索引(但是可以在date(created_timestamp)上使用索引)。

您的查询取决于DateStyle的PostgreSQL设置,因此请确保该设置始终是您所需的方式。

答案 3 :(得分:0)

大概created_timestamp实际上是日期/时间格式。因此,比较日期/时间值,而不是字符串:

created_timestamp >= '2019-05-21'::date and
created_timestamp < '2019-06-11'::date

请注意,我将between更改为两个不等式。这意味着当created_timestamp实际上具有时间成分时,代码的行为符合预期。