使用PostgreSQL处理时间

我有一个带有日期和时间字段的表.我很难理解我是如何处理这个问题的,部分是因为我不明白时间如何转换为数字.我使用以下命令创建了一个表:

CREATE TABLE tracking.time_record
(
  date date, 
  "time" time without time zone,
  id character(100)
)

我的数据示例如下:

"2012-04-18" | "18:33:19.612" | "2342342384" 

如何运行查询,以便我可以检查具有时间值>的所有id值.例如某一天晚上10点?

我意识到,因为我的时间存储在一个字符类型变量中,所以这样的东西不起作用:

SELECT * FROM tracking.time_record 
WHERE "time" > "04:33:38.884" AND date > "2012-04-18"

(这是我对时间/日期跟踪的第一次探索 – 我应该选择不同的列名)

最佳答案
到目前为止,这两个答案都没有捕捉到您的实际问题.

虽然对适当类型的明确演绎当然不会受到伤害,但没有必要. PostgreSQL自动将字符串文字强制转换为适当的类型.

您的问题源于基本语法错误:
双引号用于标识符:“MyColumn” – 仅对其他非法标识符(混合大小写,保留字,…)是必需的,应该避免开始.
单引号用于值:’string literal’.

您可能对PostgreSQL手册中identifiersconstants的精心编写的章节感兴趣.

虽然我们在这里,但不要将日期或时间用作列名.在每个SQL标准中都是reserved words,在PostgreSQL中都是类型名称.这将导致令人困惑的代码和错误消息.

我建议只使用一个时间戳列而不是单独的日期和时间:
而且你几乎肯定不希望字符(100)成为数据类型 – 特别是对于id列.这种空白填充类型基本上只是出于历史原因.请考虑使用text或varchar:

> Any downsides of using data type “text” for storing strings?

看起来像这样:

CREATE TABLE tbl (
   tbl_id text CHECK(length(id) <= 100)
 , ts timestamp
);

投放到您只需要这些组件的时间或日期,它简短且便宜:

SELECT ts::time AS the_time, ts::date AS the_date FROM tbl;

使用date_trunc()extract()以满足更多特定需求.
要查询具有时间值>的… id值某一天晚上10点:

SELECT *
FROM   tbl
WHERE  ts::time > '22:00'
AND    ts::date = '2012-04-18';

或者,对于任何连续的时间段:

...
WHERE  ts > '2012-04-18 22:00'::timestamp
AND    ts < '2012-04-19 00:00'::timestamp;

第二种形式可以更好地使用ts上的普通索引,并且在大表格的情况下会更快.

有关PostgreSQL中时间戳处理的更多信息:

> Ignoring timezones altogether in Rails and PostgreSQL

转载注明原文:使用PostgreSQL处理时间 - 代码日志