我有一台Postgresql 8.4的服务器,每天晚上01:00都要重新启动(不要求),需要连接的用户列表(即他们的时间戳是u.login> u.logout):
SELECT u.login,u.id,u.first_name FROM pref_users u WHERE u.login > u.logout and u.login > now() - interval '24 hour' ORDER BY u.login; login | id | first_name ----------------------------+----------------+------------- 2012-03-14 09:27:33.41645 | OK171511218029 | Alice 2012-03-14 09:51:46.387244 | OK448670789462 | Bob 2012-03-14 09:52:36.738625 | OK5088512947 | Sergej
但是比较u.login>现在() – 间隔’24小时’也在最后01:00之前传送用户,这是不好的,尤其是。在早上。
有没有办法从上一个01:00获得登录,而不用to_char()执行字符串杂技?
灵感来自@ Frank的评论,我运行了一些测试,并相应地调整了我的查询。这应该是1)正确2)尽可能快:
SELECT u.login,u.first_name FROM pref_users u WHERE u.login > u.logout AND u.login >= now()::date + interval '1h' ORDER BY u.login;
因为你的表中没有未来的时间戳(我假设),你不需要上限。
date_trunc(‘day’,now())与now():: date(或下面详细说明的其他替代方法)几乎相同,只是它是时间戳而不是日期。两者都会在添加间隔后产生时间戳。
以下表达式略有不同。它们产生微妙的不同结果,因为localtimestamp返回数据类型timestamp
,而now()返回timestamp with time zone
.但是,当转换为日期时,它们将转换为与本地日期相同,并且时间戳[无时区]被假定为在本地时区也是。所以当与具有时区的对应时间戳相比时,它们都在内部产生相同的UTC时间戳。 this related question有关时区处理的更多细节。
五分之一。用Postgresql 9.0测试。重复使用9.1.5:1%误差范围内的一致性结果。
SELECT localtimestamp::date + interval '1h' -- Total runtime: 351.688 ms,current_date + interval '1h' -- Total runtime: 338.975 ms,date_trunc('day',now()) + interval '1h' -- Total runtime: 333.032 ms,now()::date + interval '1h' -- Total runtime: 278.269 ms FROM generate_series (1,100000)
now():: date显然比CURRENT_DATE
稍快。