256

在比较 postgresql(Windows 中的 9.2.4 版)中的日期时,我遇到了一个奇怪的情况。
我的表中有一个列说 update_date 类型为'timestamp without timezone'。
客户可以仅使用日期(即:2013-05-03)或日期与时间(即:2013-05-03 12:20:00)搜索此字段。
该列的值为当前所有行的时间戳,并且具有相同的日期部分(2013-05-03)但时间部分不同。

当我比较这个专栏时,我得到了不同的结果。像下面这样:

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found

select * from table where update_date >= '2013-05-03' -> results found

我的问题是如何使第一个查询能够获得结果,我的意思是为什么第三个查询有效但不是第一个查询?

4

5 回答 5

402

@Nicolai 关于强制转换以及为什么任何数据的条件都是错误的都是正确的。我想您更喜欢第一种形式,因为您想避免对输入字符串进行日期操作,对吗?你不必害怕:

SELECT *
FROM table
WHERE update_date >= '2013-05-03'::date
AND update_date < ('2013-05-03'::date + '1 day'::interval);
于 2013-10-19T18:45:55.650 回答
65

当您比较update_date >= '2013-05-03'postgres 将值转换为相同类型以比较值时。因此,您的“2013-05-03”被转换为“2013-05-03 00:00:00”。

所以对于 update_date = '2013-05-03 14:45:00' 你的表达将是:

'2013-05-03 14:45:00' >= '2013-05-03 00:00:00' AND '2013-05-03 14:45:00' <= '2013-05-03 00:00:00'

这总是false

要解决此问题,请将 update_date 转换为date

select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result
于 2013-10-19T17:58:24.653 回答
15

使用range类型。如果用户输入日期:

select *
from table
where
    update_date
    <@
    tsrange('2013-05-03', '2013-05-03'::date + 1, '[)');

如果用户输入时间戳,那么您不需要该::date + 1部分

http://www.postgresql.org/docs/9.2/static/rangetypes.html

http://www.postgresql.org/docs/9.2/static/functions-range.html

于 2013-10-19T18:41:38.373 回答
6

使用日期转换与日期进行比较:试试这个:

select * from table 
where TO_DATE(to_char(timespanColumn,'YYYY-MM-DD'),'YYYY-MM-DD') = to_timestamp('2018-03-26', 'YYYY-MM-DD')
于 2018-04-24T15:10:03.190 回答
2

您也可以使用BETWEEN运算符。

这是一个简单的例子:

SELECT
    customer_id,
    payment_id,
    amount,
    payment_date
FROM
    payment
WHERE
    payment_date BETWEEN '2007-02-07' AND '2007-02-15';

您还可以选择不在这些日期之间的所有内容:

SELECT
    customer_id,
    payment_id,
    amount,
    payment_date
FROM
    payment
WHERE
    payment_date NOT BETWEEN '2007-02-07' AND '2007-02-15';

这是一个更高级的示例,涉及基于天的时间戳增量:

SELECT
    api_project.name,
    api_project.created,
    survey_response.created AS response_date,
    CASE
        WHEN survey_response.created
            BETWEEN api_project.created AND
                   (api_project.created + INTERVAL '180 days')
            THEN 'first_6_months'
        ELSE '6_months_after'
    END AS when_it_was_answered,
    EXTRACT(DAYS FROM survey_response.created - api_project.created)
      AS days_since_response
FROM
    bfb_survey_surveyresponseppent
于 2021-12-07T19:43:58.003 回答