4

我有一个带有datetime字段的表。我很难理解如何处理这个问题,部分原因是我不明白如何将时间转换为数字。我使用以下命令制作了一个表格:

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 pm

我意识到,由于我的时间存储在字符类型变量中,所以这样的事情不起作用:

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

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

4

3 回答 3

10

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

虽然显式强制转换为适当的类型肯定不会有什么坏处,但也没有必要。PostgreSQL 自动将字符串文字强制转换为适当的类型。

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

您可能对PostgreSQL 手册中关于标识符常量的精心编写的章节感兴趣。

当我们这样做时,永远不要使用dateortime作为列名。两者都是每个 SQL 标准中的保留字和 PostgreSQL 中的类型名称。这将导致混淆代码和错误消息。

我建议只使用单个timestamp列而不是单独的dateand :而且您几乎time肯定不希望character(100)用作数据类型,尤其是对于列。这种空白填充类型基本上只是出于历史原因。考虑或代替:idtextvarchar

可能看起来像这样:

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

投射到timedate只需要这些组件的地方,它既短又便宜:

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

使用date_trunc()extract()用于更具体的需求。
要查询在某一天的时间值 > 10 pm 的 ... id 值

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更好地使用普通索引,并且在这种情况下对于大表会更快。

timestamp有关在 PostgreSQL 中处理的更多信息:

于 2012-04-25T05:53:21.290 回答
4

您可以使用date_part函数来获取小时

select id 
from tracking.time_record
where date_part('hour', time) >= 22
  and date = '2012-04-18'

>= 22 而不是 > 22 是为了捕捉晚上 10 点到 11 点之间的间隔。这也捕获了晚上 10:00:00。但调整查询以捕捉正确的间隔并不难

您在这里有一个工作示例。

于 2012-04-24T13:26:54.067 回答
3

比较时间和日期值在 postgresql 中应该可以正常工作,只需确保将字符串转换为适当的类型:

SELECT * FROM tracking.time_record 
WHERE "time" > time '04:33:38.884' AND "date" > date '2012-04-18'
于 2012-04-24T13:36:46.040 回答