sql >> Database teknologi >  >> RDS >> PostgreSQL

Rails/Postgresql SQL forskelle m/ datoer

Versionen af ​​generate_series som du bruger, arbejder med tidsstempler, ikke datoer. Så din '2012-10-14' og current_date bliver konverteret til timestamp with time zone s og generate_series producerer et sæt timestamp with time zone s; sammenligne disse:

=> select generate_series('2012-10-14', current_date, '1 day');
    generate_series     
------------------------
 2012-10-14 00:00:00-07
 2012-10-15 00:00:00-07
 2012-10-16 00:00:00-07
 2012-10-17 00:00:00-07
 2012-10-18 00:00:00-07
 2012-10-19 00:00:00-07
 2012-10-20 00:00:00-07
(7 rows)

=> select generate_series('2012-10-14', current_date::timestamp, '1 day');
   generate_series   
---------------------
 2012-10-14 00:00:00
 2012-10-15 00:00:00
 2012-10-16 00:00:00
 2012-10-17 00:00:00
 2012-10-18 00:00:00
 2012-10-19 00:00:00
 2012-10-20 00:00:00
(7 rows)

Den første har tidszoner, den anden har ikke.

Men current_date bliver altid konverteret til et tidsstempel med databasesessionens tidszonejustering anvendt. Rails-sessionen vil tale til databasen i UTC, din psql session bruger sandsynligvis ET.

Hvis du manuelt angiver den aktuelle dato og eksplicit arbejder med timestamp s:

select generate_series('2012-10-14'::timestamp, '2012-10-20'::timestamp, '1 day')

så får du de samme syv resultater i begge, fordi der ikke er nogen tidszone i sigte til at lave noget rod i tingene.

Den nemmeste måde at ignorere tidszoner på er at bruge heltalsversionen af ​​generate_series og det faktum, at tilføjelse af et heltal til en dato behandler heltal som et antal dage:

select '2012-10-14'::date + generate_series(0, 6)

Det vil give dig de samme syv dage uden tidszoneinterferens. Du kan stadig bruge current_date (som ikke har nogen tidszone, da SQL-datoer ikke har tidszoner) ved at bemærke, at forskellen mellem to datoer er antallet af dage mellem dem (et heltal):

=> select '2012-10-14'::date + generate_series(0, current_date - '2012-10-14');
  ?column?  
------------
 2012-10-14
 2012-10-15
 2012-10-16
 2012-10-17
 2012-10-18
 2012-10-19
 2012-10-20
(7 rows)

og fra Rails:

> pp ActiveRecord::Base.connection.execute("select '2012-10-14'::date + generate_series(0, 6)").to_a
[{"?column?"=>"2012-10-14"},
 {"?column?"=>"2012-10-15"},
 {"?column?"=>"2012-10-16"},
 {"?column?"=>"2012-10-17"},
 {"?column?"=>"2012-10-18"},
 {"?column?"=>"2012-10-19"},
 {"?column?"=>"2012-10-20"}]

BTW, jeg hader tidszoner, hader og foragter dem.




  1. Ændre brugerdefineret type i SQL Server

  2. CSV i SQL-udvikler...

  3. PHP, MySQL og tidszoner

  4. Hvad knytter Hibernate en boolesk datatype til, når der som standard bruges en Oracle-database?