sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL:mezi datem a časem

Očekávali jste 1-01-01 ... 1-12-31 ... ale jak má PostgreSQL vědět, co tím myslíte?

Vstupní řetězcové literály jsou interpretovány podle nastavení vaší aktuální relace (která je výchozím nastavením pro obecná nastavení v postgressql.conf pokud nebude přehlasován). Konkrétně datestyle :

DateStyle (string )

Nastavuje formát zobrazení pro hodnoty data a času a také pravidla pro interpretaci nejednoznačných vstupních hodnot data. Z historických důvodů tato proměnná obsahuje dvě nezávislé součásti:specifikaci výstupního formátu (ISO , Postgres , SQL nebo German ) a specifikaci vstupu/výstupu pro objednání rok/měsíc/den (DMY , MDY nebo YMD ). Ty lze nastavit samostatně nebo společně. Klíčová slovaEuro a European jsou synonyma pro DMY; klíčová slova US ,NonEuro a NonEuropean jsou synonyma pro MDY . Viz Oddíl 8.5 Pro více informací. Vestavěné výchozí nastavení je ISO, MDY , ale initdb inicializuje konfigurační soubor s nastavením, které odpovídá chování zvoleného lc_time národní prostředí.

(Zatímco výstupní formát je většinou určen lc_time .)

Ve vašem případě je zmrzačený literál časového razítka 1-12-31 23:59:59 je zjevně interpretováno jako:

D-MM-YY h24:mi:ss

Zatímco byste doufali v:

Y-MM-DD h24:mi:ss

3 možnosti

  1. Nastavte datestyle takže interpretuje literály stejným způsobem jako vy. Možná ISO, YMD ?

  2. Použijte to_timestamp() interpretovat řetězcový literál dobře definovaným způsobem - nezávisle na jiných nastaveních. Mnohem lepší.

     SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
    
  3. Ještě lépe použijte formát ISO 8601 (YYYY-MM-DD ) pro všechny literály datetime. To je jednoznačné a nezávislé na jakémkoli nastavení .

     SELECT '2001-12-31 23:59:59'::timestamp;
    

Přepsat dotaz

Váš dotaz je zpočátku chybný. Řešit dotazy na rozsah jinak. Jako:

SELECT d.given_on 
FROM   documents_document d
WHERE  EXTRACT('month' FROM d.given_on) = 1
AND    d.given_on >= '2001-01-01 0:0'
AND    d.given_on <  '2002-01-01 0:0'
ORDER  BY d.created_on DESC;

Nebo ještě jednodušeji:

SELECT d.given_on 
FROM   documents_document d
WHERE  d.given_on >= '2001-01-01 0:0'
AND    d.given_on <  '2001-02-01 0:0'
ORDER  BY d.created_on DESC;

Typy rozsahů v PostgreSQL 9.2 nebo novějším mohou být zajímavé.



  1. Jak migrovat databáze a datové soubory

  2. Jak zkontrolovat, zda existuje uložená procedura před jejím vytvořením

  3. Jak získat rozdíl dnů/měsíců/roků (datediff) mezi dvěma daty?

  4. GROUP BY s MAX (DATE)