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

Как да напиша функция в plpgsql, която сравнява дата с клеймо за време без часова зона?

Какво каза Павел.

Нещо повече, нищо не показва необходимост от PL/pgSQL като начало. Обикновен (подготвен) SELECT твърдението може да го направи. Или SQL функция, ако искате да я запазите в базата данни. Вижте:

И относно:

Определете включваща/изключителна горна/долна граница точно за да се избегнат изненадващи ъглови резултати. Когато сравнявате timestamp колона до date , последният е принуден към клеймото за време, обозначаващо първия случай на деня:YYYY.MM.DD 00:00:00 .

Вашето запитване гласи:

measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... което ще включва всички firstDate , но изключете всички от lastDate с изключение на първия (общ) случай в 00:00 . Обикновено не това, което искате. Като се има предвид вашата формулировка, предполагам, че това е, което наистина искате:

CREATE OR REPLACE FUNCTION get_measurements_by_node_and_date(node_id integer
                                                           , firstDate date
                                                           , lastDate date) 
  RETURNS TABLE (measurement_id integer
               , node_id integer
               , carbon_dioxide float8
               , hydrocarbons float8
               , temperature float8
               , humidity float8
               , air_pressure float8
               , measurement_timestamp timestamp)
  LANGUAGE sql STABLE AS
$func$
   SELECT m.id
        , m.node_id
        , m.carbon_dioxide
        , m.hydrocarbons
        , m.temperature
        , m.humidity
        , m.air_pressure
        , m.measurement_timestamp -- AS measure  -- just documentation
   FROM   public.measurements_lora m
   WHERE  m.node_id = _node_id
   AND    m.measurement_timestamp >= firstDate::timestamp
   AND    m.measurement_timestamp < (lastDate + 1)::timestamp  -- ①!
$func$;

① Това включва всички lastDate , и ефикасно. Можете просто да добавите/извадите integer стойност до/от date за добавяне/изваждане на дни . Изричното преобразуване към ::timestamp не е задължително, тъй като датата ще бъде принудена в израза автоматично. Но тъй като се опитваме да изясним объркването тук...

Свързани:

Настрана 1:

timestamp стойностите не са форматиран, точка. Те са просто стойности на клеймо за време (вътрешно съхранени като брой микросекунди от епохата). Дисплеят е напълно отделен от стойността и може да се регулира по сто и един начина, без да се променя стойността . Отървете се от това погрешно схващане, за да разберете по-добре какво се случва. Вижте:

Настрана 2:

За коварната природа на SQL BETWEEN :

Отстрани 3:

Помислете за легални идентификатори с малки букви в Postgres. first_date вместо firstDate . Вижте:

Свързани:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Време за изчакване на заявка в pg-promise

  2. Защо всичките ми таблици в Rails 4/Postgres се създават с измерение 1?

  3. Асинхронен DBAppender с logback

  4. Как да видите коя версия на Postgres работи

  5. Съпоставяне на сериен тип PostgreSQL с анотации за хибернация