仅选择今天(从午夜开始)时间戳

时间:2012-03-15 09:20:46

标签: postgresql date datetime timestamp postgresql-8.4

我有一台带有PostgreSQL 8.4的服务器,每天晚上01:00重新启动(不要问)并且需要获取已连接用户的列表(即他们的时间戳是u.login > u.logout):< / p>

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 > now()-interval '24 hour'也会在最后01:00之前传递用户,这很糟糕,尤其是。在早上。

有没有有效的方法自上次01:00以来获取登录而不使用to_char()进行字符串杂技?

5 个答案:

答案 0 :(得分:41)

受到@Frank评论的启发,我运行了一些测试并相应调整了我的查询。这应该是1)正确和2)尽可能快:

SELECT u.login, u.id, 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(或下面详述的其他一些替代方案)几乎相同,只是它返回timestamp而不是date。添加timestamp后,两者都会产生interval


下面的表达式略有不同。它们会产生微妙的不同结果,因为localtimestamp返回数据类型timestampnow()返回timestamp with time zone。但是当转换为date时,要么转换为相同的本地日期,并且假定timestamp [without time zone]也在本地时区。因此,与相应的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略快。

答案 1 :(得分:12)

从01:00开始,仅获取当天的时间戳的简单方法是过滤 CURRENT_DATE + interval '1 hour'

所以你的查询应该是这样的:

SELECT u.login, u.id, u.first_name
FROM pref_users u
WHERE u.login > u.logout AND
      u.login > CURRENT_DATE + interval '1 hour'
ORDER BY u.login;

希望有所帮助。

答案 2 :(得分:8)

select * from termin where DATE(dateTimeField) >= CURRENT_DATE AND DATE(dateTimeField) < CURRENT_DATE + INTERVAL '1 DAY'

这对我有用 - 它选择今天日期的所有行。

答案 3 :(得分:7)

select * from termin where DATE(dateTimeField) = '2015-11-17'

这对我有用!

答案 4 :(得分:3)

where 
    u.login > u.logout 
    and     
    date_trunc('day', u.login) = date_trunc('day', now()) 
    and 
    date_trunc('hour', u.login) >= 1
相关问题