2012-01-12 44 views
1

我有一个匹配表。该表具有名为matchdate的列,该列是datetime字段。如何将一整天匹配到日期时间字段?

如果非要2011-12-01 3场比赛:

  • 2011-12-01 12:00:00
  • 2011-12-01 13点25分00秒
  • 2011-12-01 16:00:00

如何查询?如何查询单个日期的所有匹配?

我已经看过date_trunc()to_char()
是不是有一些"select * where datetime in date"功能?

回答

5

如果您想要简单的语法,请将timestamp的值转换为date。就像这样:

SELECT * 
FROM tbl 
WHERE timestamp_col::date = '2011-12-01'; -- date literal 

然而,与大表,这将是更快:

SELECT * 
FROM tbl 
WHERE timestamp_col >= '2011-12-01 0:0' -- timestamp literal 
AND timestamp_col < '2011-12-02 0:0'; 

原因:第二个查询没有在表中变换的每一个值,并且可以利用一个简单的指数时间戳列。表达式是sargable

注意排除了上限(<而不是<=)以进行正确选择。
可以弥补通过创建一个index on an expression这样的:

CREATE INDEX tbl_ts_date_idx ON tbl (cast(timestamp_col AS date)); 

那么查询的第一个版本将是一样快,因为它得到。

+1

你可以得到的Rails产生半开'[2011-12-01,2011-12-02)'版本'。凡(:日期=>'2011-12-01'...'2011-12-02')',双点范围将使用[2011-12-01,2011-12-02]和BETWEEN。当使用'> ='和'<'时,PostgreSQL是否也会将所有东西都转换为日期?或者它能够足够聪明地知道将文字转换为时间戳会产生相同的效果并减少工作量? – 2012-01-12 18:47:02

+0

@ muistooshort:Postgres在这种情况下足够聪明。这将导致我的第二个查询。 – 2012-01-12 22:06:02

1

不知道如果我失去了一些东西很明显这里,但我想你可以只

select * from table where date_trunc('day', ts) = '2011-12-01'; 
0

只需使用SQL函数之间,像这样:

SELECT * FROM table WHERE date BETWEEN '2011-12-01' AND '2011-12-02' 

您可能需要包括倍日期文字,但这应该包括情人限制并排除上限。

从铁轨我相信你能做到:

.where(:between => '2011-12-01'..'2011-12-02') 
+0

你想要'.where(:date =>'2011-12-01'...'2011-12-02')':':date''而不是':between'和一个三点范围内的半开放[2011-12-01,2011-12-02]'间隔一个完全关闭的[2011-12-01,2011-12-02]'区间。 '..'确实在SQL中作为BETWEEN结束,'...'最后使用'> ='/'<'对结束。 – 2012-01-12 18:38:30

相关问题