就简化问题而言,我有以下疑问:
SELECT * FROM table WHERE (DATE_TRUNC('day',create_time ) > now() - interval '2 days');
运行解释我得到了这个:
-> Seq Scan on table (cost=0.00..1.62 rows=10 width=232)
Filter: (date_trunc('day'::text, create_time) > (now() - '2 days'::**interval**))
正如我所强调的那样,此操作(现在() - 间隔' 2天')会返回一个间隔,但我需要它作为时间戳。
在这种情况下,我如何从间隔转换为时间戳或类似的东西?
谢谢大家的答案,但我认为解释不是很好, 这是详细的问题:
出于性能目的,我们在这里有一个名为' transactions'每天的子表格,例如" transactions_2015_05_29'。
在每个子表上,我们有以下约束:
CONSTRAINT transactions_2015_05_29_create_time_check CHECK (date_trunc('day'::text, create_time) = '2015-05-29 00:00:00'::timestamp without time zone)
当我们执行以下操作时,请说明'我们得到以下查询:
说明:
explain SELECT * FROM pp_transactions WHERE (DATE_TRUNC('day', create_row_time) < current_date + interval '1 day');
"Result (cost=0.00..120.52 rows=731 width=232)"
" -> Append (cost=0.00..120.52 rows=731 width=232)"
" -> Seq Scan on transactions (cost=0.00..1.70 rows=10 width=232)"
" Filter: (date_trunc('day'::text, create_time) < (('now'::text)::date + '1 day'::interval))"
" -> Seq Scan on **transactions_2015_05_28** pp_transactions (cost=0.00..14.65 rows=103 width=232)"
" Filter: (date_trunc('day'::text, create_time) < '2015-05-30 00:00:00'::timestamp without time zone)"
" -> Seq Scan on **transactions_2015_05_29** transactions (cost=0.00..16.98 rows=103 width=232)"
" Filter: (date_trunc('day'::text, create_time) < (('now'::text)::date + '1 day'::interval))"
" -> Seq Scan on **transactions_2015_05_30** transactions (cost=0.00..16.98 rows=103 width=232)"
" Filter: (date_trunc('day'::text, create_time) < (('now'::text)::date + '1 day'::interval))"
" -> Seq Scan on **transactions_2015_05_31** transactions (cost=0.00..16.98 rows=103 width=232)"
" Filter: (date_trunc('day'::text, create_time) < (('now'::text)::date + '1 day'::interval))"
正如您所看到的,有些桌子不应该存在。 但是如果我们运行以下查询,我会在explain上得到正确的结果:
说明:
explain select * FROM pp_transactions WHERE (DATE_TRUNC('day', create_row_time) < '2015-05-30 00:00:00');
"Result (cost=0.00..30.76 rows=216 width=232)"
" -> Append (cost=0.00..30.76 rows=216 width=232)"
" -> Seq Scan on transactions (cost=0.00..1.46 rows=10 width=232)"
" Filter: (date_trunc('day'::text, create_time) < '2015-05-30 00:00:00'::timestamp without time zone)"
" -> Seq Scan on **transactions_2015_05_28** pp_transactions (cost=0.00..14.65 rows=103 width=232)"
" Filter: (date_trunc('day'::text, create_time) < '2015-05-30 00:00:00'::timestamp without time zone)"
" -> Seq Scan on **transactions_2015_05_29** pp_transactions (cost=0.00..14.65 rows=103 width=232)"
" Filter: (date_trunc('day'::text, create_time) < '2015-05-30 00:00:00'::timestamp without time zone)"
因此,第一个查询必须表现为第二个查询。
答案 0 :(得分:1)
- 您可以向TIMESTAMP添加或减去INTERVAL以生成另一个TIMESTAMP
醇>TIMESTAMP'1999-12-11'+ INTERVAL'19 days'= TIMESTAMP'1999-12-30'
这对我来说是个约会(2天前在CEST 19:08),并根据手册(再次)now()生成时间戳:
(now() - '2 days'::**interval**)
now()是一个函数,间隔是“2天”。
答案 1 :(得分:0)
理论推理为什么没有DB供应商提供的官方转换(与您的问题的标题相关):
转换此类不兼容类型的唯一方法是引入固定(但任意)的开始时间戳,在其上添加间隔(更好地说持续时间)并确定最终时间戳,然后是结果。请注意,由于时区效应(夏令时),转换可能取决于开始时间戳的选择,因为一天并不总是24小时。
然而,放弃这种奇怪的转换可能更健康。这就像比较苹果和橘子。或者在几何解释中:如何将距离转换为点?
对于PostgreSQL语句的具体分析,请同时查看PostgreSQL - documentation。我想知道为什么你认为你得到now() - interval '2 days'
的结果。你能否展示你观察到的输出?但也许你没有观察到你的输出但只是对SQL-EXPLAIN的文本感到困惑,其中表达式(now() - '2 days'::**interval**)
中的文本“interval”与前面的部分“2天”相关,而不是整个表达式。