关于postgresql:仅选择今天(从午夜开始)时间戳

Select today's (since midnight) timestamps only

我有一个PostgreSQL 8.4的服务器,每天晚上01:00(不要问)重新启动,需要获得一个连接用户列表(即他们的时间戳是u.login > u.logout)。

1
2
3
4
5
6
7
8
9
10
11
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()进行字符串杂技?


受到@frank评论的启发,我进行了一些测试,并相应地修改了我的查询。这应该是1)正确和2)尽快:

1
2
3
4
5
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。两种方法都会在添加interval后产生timestamp

以下表达式的执行方式略有不同。由于localtimestamp返回数据类型timestamp,而now()返回timestamp with time zone,它们产生的结果略有不同。但是,当强制转换为date时,要么转换为相同的本地日期,而timestamp [without time zone]也假定位于本地时区。因此,与对应的timestamp with time zone相比,它们都会在内部产生相同的UTC时间戳。有关此相关问题中时区处理的更多详细信息。

最好的五。使用PostgreSQL 9.0进行测试。重复9.1.5:1%误差范围内结果一致。

1
2
3
4
5
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


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

所以您的查询应该如下所示:

1
2
3
4
5
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;

希望有帮助。


1
SELECT * FROM termin WHERE DATE(dateTimeField) >= CURRENT_DATE AND DATE(dateTimeField) < CURRENT_DATE + INTERVAL '1 DAY'

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


1
SELECT * FROM termin WHERE DATE(dateTimeField) = '2015-11-17'

这对我很管用!


1
2
3
4
5
6
WHERE
    u.login > u.logout
    AND    
    date_trunc('day', u.login) = date_trunc('day', now())
    AND
    date_trunc('hour', u.login) >= 1