2012-04-24 71 views
3

我有一个表datetime字段。我很难理解我如何处理这个问题,部分原因是我不明白如何将时间转换为数字。使用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 pm

我意识到,我的时间存储在一个字符类型变量,因此这样的事情不工作:

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

(这是我的时间/日期跟踪的第一口探井 - 我也许应该选择不同列名)

+0

为什么不日期+时间合并成/时间戳没有时区?它会使比较更容易,你可以随时提取相关部分,如果你想要它们。 – wildplasser 2012-04-24 14:20:37

+0

这是一个很好的观点。现在我正在更好地理解时间戳的工作方式,我将在未来做到这一点。 – djq 2012-04-24 15:30:34

回答

10

无论答案迄今捕获您的实际问题(一个或多个)。

虽然显式转换为相应类型当然不会造成伤害,但不需要。 PostgreSQL自动将一个字符串文字强制转换为适当的类型。

你的问题,从基本的语法错误干:
双引号标识符"MyColumn" - 只有必要应避免开始与其他非法标识符(混合的情况下,保留字,..) 。
单引号用于'string literal'

您可能会对PostgreSQL手册的identifiersconstants的书面章节感兴趣。

虽然我们在这,从未使用datetime列名。 PostgreSQL中的每个SQL标准和类型名称都是reserved words。这会导致代码和错误消息混淆。

我会建议只使用一个单一的timestamp列,而不是单独的datetime: 你几乎肯定不希望character(100)数据类型,不断 - 尤其不适合的id列。这种空白填充类型基本上只是出于历史原因。考虑textvarchar代替:

看起来是这样的:

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点的... 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中:

+0

顺便说一句,我怀疑你实际上是想为你的'id'使用'character(100)'。这种空白填充类型基本上只是出于历史原因。请考虑['text或varchar'](http://www.postgresql.org/docs/current/interactive/datatype-character.html)。 – 2012-04-25 13:44:52

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。但its't很难适应查询捉住右间隔

你有一个工作的例子here

+1

哇 - 'sqlfiddle'!谢谢。 – djq 2012-04-24 15:31:33

+0

'date_part()'也是不必要的。 '“时间”> '22:00''会。 – 2012-04-25 05:58:40

3

比较时间和日期值应在PostgreSQL的正常工作,只是确保你转换你的字符串到合适的类型:

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

请注意,这将在上午4:33之后的2012-04-18起发现记录。 (所以在这一天之前什么都没有,也没有任何一天在上午4:33之前)。你可能想要的是一个时间戳列。 – Andrew 2012-04-25 00:21:27

+0

在这种情况下不需要铸造(虽然没有伤害)。 Postgres在此自动将字符串文字强制转换为匹配类型。语法错误是问题。 – 2012-04-25 05:57:11

+0

你说得对。我仍然会推荐演员。比较字符串或日期还是别的吗?如果不看表格规格,你真的无法分辨。 – user1346466 2012-04-25 09:42:06