Oczekiwałeś 1-01-01 ... 1-12-31
... ale skąd PostgreSQL ma wiedzieć, co przez to rozumiesz?
Literały ciągu wejściowego są interpretowane zgodnie z ustawieniami bieżącej sesji (które domyślnie są ustawieniami ogólnymi w postgressql.conf
chyba że zostanie unieważniony). W szczególności datestyle
:
DateStyle
(string
)
Ustawia format wyświetlania wartości daty i godziny, a także zasady interpretacji niejednoznacznych wartości wejściowych daty. Ze względów historycznych ta zmienna zawiera dwa niezależne składniki:specyfikację formatu wyjściowego (ISO
, Postgres
, SQL
lub German
) oraz specyfikację wejścia/wyjścia dla zamawiania rok/miesiąc/dzień (DMY
, MDY
lub YMD
). Można je ustawić osobno lub razem. Słowa kluczoweEuro
i European
są synonimami DMY
; słowa kluczowe US
,NonEuro
i NonEuropean
są synonimami MDY
. Zobacz Sekcję8.5 po więcej informacji. Wbudowana wartość domyślna to ISO, MDY
, ale initdb zainicjuje plik konfiguracyjny z ustawieniem odpowiadającym zachowaniu wybranego lc_time
lokalizacja.
(Podczas gdy format wyjściowy jest określany głównie przez lc_time
.)
W twoim przypadku, literal sygnatury czasowej, który został uszkodzony 1-12-31 23:59:59
jest oczywiście interpretowane jako:
D-MM-YY h24:mi:ss
Chociaż byś liczył na:
Y-MM-DD h24:mi:ss
3 opcje
-
Ustaw
datestyle
aby interpretował literały w taki sam sposób jak ty. MożeISO, YMD
? -
Użyj
to_timestamp()
interpretować literał ciągu w dobrze zdefiniowany sposób - niezależnie od innych ustawień. Znacznie lepiej.SELECT to_timestamp('1-12-31 23:59:59', 'Y-MM-DD h24:mi:ss');
-
Jeszcze lepiej, użyj formatu ISO 8601 (
YYYY-MM-DD
) dla wszystkich literałów daty i godziny. To jest jednoznaczne i niezależne od jakichkolwiek ustawień .SELECT '2001-12-31 23:59:59'::timestamp;
Przepisz zapytanie
Twoje zapytanie jest na początku błędne. Obsługuj zapytania o zakres w inny sposób. Na przykład:
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;
Lub jeszcze prościej:
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 zakresów w PostgreSQL 9.2 lub nowszych mogą być interesujące.