我有一台装有 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 > now()-interval '24 hour'
也会在最后 01:00 之前交付用户,这很糟糕,尤其是。在早上。
有没有什么有效的方法可以获取自上次 01:00 以来的登录信息,而无需使用 to_char()
进行字符串杂技?
最佳答案
这应该 1) 正确并且 2) 尽可能快:
SELECT u.login, u.id, u.first_name
FROM pref_users u
WHERE u.login >= now()::date + interval '1h'
AND u.login > u.logout
ORDER BY u.login;
由于您的表中没有 future 的时间戳(我假设),因此您不需要上限。
一些等价的表达方式:
SELECT localtimestamp::date + interval '1h'
, current_date + interval '1h'
, date_trunc('day', now()) + interval '1h'
, now()::date + interval '1h'
now()::date
过去的执行速度比 CURRENT_DATE
稍快在旧版本中,但在现代 Postgres 中不再如此。但两者都比 LOCALTIMESTAMP
快由于某种原因在 Postgres 14 中。
date_trunc('day', now()) + interval '1h'
略有不同,因为它返回 timestamptz
。但是根据当前 session 的 timezone
设置,与 timestamp
列 login
相比,它被强制为 timestamp
, 做同样的事情。
参见:
要返回前一天的行而不是在本地时间 00:00 到 01:00 之间发出时不返回任何内容,请改用:
WHERE u.login >= (LOCALTIMESTAMP - interval '1h')::date + interval '1h'
关于postgresql - 仅选择今天(从午夜开始)的时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9716868/