sql >> Database >  >> RDS >> PostgreSQL

Hoe schrijf ik een functie in plpgsql die een datum vergelijkt met een tijdstempel zonder tijdzone?

Wat Pavel zei.

Bovendien wijst niets erop dat er om te beginnen PL/pgSQL nodig is. Een gewone (voorbereide) SELECT verklaring kan het. Of een SQL-functie, als u deze in de database wilt behouden. Zie:

En over:

Definieer inclusief/exclusief boven-/ondergrens precies om verrassende hoekkastresultaten te voorkomen. Bij het vergelijken van een timestamp kolom naar een date , de laatste wordt gedwongen tot het tijdstempel dat de eerste instantie van de dag aangeeft:YYYY.MM.DD 00:00:00 .

Uw vraag zegt:

measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... die alle firstDate . zou bevatten , maar alle lastDate uitsluiten behalve de eerste (gewone) instantie om 00:00 . Meestal niet wat je wilt. Gezien je formulering, denk ik dat dit is wat je echt wilt:

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$;

① Dit omvat alle lastDate , en efficiënt. Je kunt gewoon een integer waarde naar / van een date dagen optellen / aftrekken . De expliciete cast naar ::timestamp is optioneel omdat de datum automatisch in de uitdrukking zou worden gedwongen. Maar aangezien we hier verwarring proberen op te ruimen ...

Gerelateerd:

Terzijde 1:

Nee. timestamp waarden zijn niet geformatteerd, punt. Het zijn slechts tijdstempelwaarden (intern opgeslagen als het aantal microseconden sinds het tijdperk). De weergave staat volledig los van de waarde en kan op honderd-en-een manieren worden aangepast zonder de waarde te wijzigen . Weg met deze misvatting om beter te begrijpen wat er aan de hand is. Zie:

Terzijde 2:

Over de slinkse aard van SQL BETWEEN :

Terzijde 3:

Overweeg legale identificatiecodes in kleine letters in Postgres. first_date in plaats van firstDate . Zie:

Gerelateerd:



  1. Hoe kan ik een mysql-resultaat sorteren op een lijst met geprioriteerde ID's?

  2. Hoe de banen in orakel uit te voeren?

  3. Werken met gebeurtenissen in MySQL

  4. Snelle manier om aaneengeschakelde strings in Oracle te genereren