web-dev-qa-db-ja.com

今日(真夜中以降)のタイムスタンプのみを選択

私は毎晩01:00にリブートされるPostgreSQL 8.4のサーバーを持っています(尋ねないでください)。接続しているユーザーのリストを取得する必要があります(つまり、タイムスタンプは_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より前のユーザーも配信されます。これは特に悪いことです。朝に。

to_char()で文字列アクロバットを行わずに最後の01:00以降のログインを取得するに効率的な方法はありますか?

34

@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はデータ型 timestamp を返すのに対し、now()timestamp with time zone 。ただし、dateにキャストすると、どちらも同じlocal日付に変換され、timestamp [without time zone]はローカルタイムゾーンにあると推定されます。も。したがって、対応するtimestamp with time zoneと比較すると、それらはすべて内部的に同じUTCタイムスタンプになります。タイムゾーン処理の詳細については、 関連する質問 をご覧ください。

5つのベスト。 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 よりわずかに高速です。

47

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;

お役に立てば幸いです。

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

これは私にとってはうまくいきます-今日の日付を持つすべての行を選択します。

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

これは私にとってはうまくいきます!

8
Vivegan
where 
    u.login > u.logout 
    and     
    date_trunc('day', u.login) = date_trunc('day', now()) 
    and 
    date_trunc('hour', u.login) >= 1
3
Clodoaldo Neto