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

Hvordan skriver jeg en funktion i plpgsql, der sammenligner en dato med et tidsstempel uden tidszone?

Hvad Pavel sagde.

Hvad mere er, intet indikerer et behov for PL/pgSQL til at begynde med. En almindelig (forberedt) SELECT statement kan gøre det. Eller en SQL-funktion, hvis du vil bevare den i databasen. Se:

Og vedrørende:

Definer inklusive/eksklusiv øvre/nedre grænse præcist for at undgå overraskende resultater i hjørnekassen. Når du sammenligner et timestamp kolonne til en date , er sidstnævnte tvunget til tidsstemplet, der angiver dagens første forekomst:YYYY.MM.DD 00:00:00 .

Din forespørgsel siger:

measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... som ville omfatte alle firstDate , men ekskluder alle lastDate undtagen det første (almindelige) tilfælde kl. 00:00 . Typisk ikke hvad du ønsker. I betragtning af din formulering, formoder jeg, at dette er, hvad du virkelig ønsker:

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

① Dette inkluderer alle lastDate og effektivt. Du kan bare tilføje/fratrække et integer værdi til/fra en date at tilføje / trække dage fra . Den eksplicitte cast til ::timestamp er valgfri, da dato ville blive tvunget automatisk i udtrykket. Men da vi prøver at rydde op i forvirringen her ...

Relateret:

Bortset fra 1:

Nej. timestamp værdier er ikke formateret, punktum. De er blot tidsstempelværdier (internt gemt som antallet af mikrosekunder siden epoken). Visningen er fuldstændig adskilt fra værdien og kan justeres på hundrede og én måde uden at ændre værdien . Slip af med denne misforståelse for bedre at forstå, hvad der foregår. Se:

Bortset fra 2:

Om SQL BETWEENs lumske karakter :

Bortset fra 3:

Overvej lovlige identifikatorer med små bogstaver i Postgres. first_date i stedet for firstDate . Se:

Relateret:



  1. En guide til Pgpool til PostgreSQL:Anden del

  2. Delphi - forebygge mod SQL-injektion

  3. Hvordan returneres NULL, når resultatet er tomt?

  4. php-kode til at teste pdo er tilgængelig?