sql >> Databasteknik >  >> RDS >> PostgreSQL

Välj endast dagens (sedan midnatt) tidsstämplar

Inspirerad av @Franks kommentar körde jag några tester och anpassade min fråga efter det. Detta ska vara 1) korrekt och 2) så snabbt som möjligt:

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;

Eftersom det inte finns några framtida tidsstämplar i din tabell (förmodar jag), behöver du ingen övre gräns.
date_trunc('day', now()) är nästan samma som now()::date (eller några andra alternativ som beskrivs nedan), bara att den returnerar timestamp istället för ett date . Båda resulterar i en timestamp i alla fall efter att ha lagt till ett interval .

Nedanstående uttryck fungerar något annorlunda. De ger subtilt olika resultat eftersom localtimestamp returnerar datatypen timestamp medan now() returnerar timestamp with time zone . Men när cast till date , antingen konverteras till samma lokala datum och en timestamp [without time zone] antas också vara i den lokala tidszonen. Så jämfört med motsvarande timestamp with time zone de resulterar alla i samma UTC-tidsstämpel internt. Mer information om tidszonshantering i den här relaterade frågan.

Bäst av fem. Testad med PostgreSQL 9.0. Upprepad med 9.1.5:konsekventa resultat inom 1 % felmarginal.

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 är uppenbarligen något snabbare än CURRENT_DATE .



  1. Hur RADIANS() fungerar i MariaDB

  2. CTE-fel:Typerna matchar inte mellan ankaret och den rekursiva delen

  3. opatch prereq

  4. Postgres Alter Kolumn Heltal till Boolean