PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Rails/Postgresql SQL разлики с дати

Версията на generate_series който използвате, работи с времеви печати, а не с дати. Така че вашият '2012-10-14' и current_date се преобразуват в timestamp with time zone s и generate_series произвежда набор от timestamp with time zone с; сравнете тези:

=> 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)

Първият има часови зони, вторият не.

Но current_date винаги се преобразува във времева марка с приложена корекция на часовата зона на сесията на базата данни. Rails сесията ще говори с базата данни в UTC, вашият psql сесията вероятно използва ET.

Ако ръчно посочите текущата дата и изрично работите с timestamp s:

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

тогава ще получите едни и същи седем резултата и в двата, защото не се вижда часова зона, която да обърка нещата.

Най-лесният начин да игнорирате часовите зони е да използвате целочислената версия на generate_series и фактът, че добавянето на цяло число към дата третира цялото число като брой дни:

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

Това ще ви даде същите седем дни без намеса в часовата зона. Все още можете да използвате current_date (което няма часова зона, тъй като SQL датите нямат часови зони), като отбележим, че разликата между две дати е броят на дните между тях (цяло число):

=> 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)

и от 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"}]

Между другото, мразя часовите зони, мразя и ги презирам.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Набор на JDBCTemplate вложен POJO с BeanPropertyRowMapper

  2. PostgreSQL във възход:открития на Postgres за 2018 г. и тенденции за 2019 г.

  3. Анализ на лог на PostgreSQL с pgBadger

  4. Писане на заявка за множество таблици в php

  5. PostgreSQL как да свържете стойността на интервала '2 дни'