sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur skriver jag en funktion i plpgsql som jämför ett datum med en tidsstämpel utan tidszon?

Vad Pavel sa.

Dessutom tyder ingenting på ett behov av PL/pgSQL till att börja med. En vanlig (förberedd) SELECT uttalande kan göra det. Eller en SQL-funktion, om du vill bevara den i databasen. Se:

Och angående:

Definiera inklusive/exklusiv övre/nedre gräns exakt för att undvika överraskande hörnfallsresultat. När du jämför en timestamp kolumnen till ett date , den senare tvingas till tidsstämpeln som anger dagens första instans:YYYY.MM.DD 00:00:00 .

Din fråga säger:

measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... som skulle inkludera alla firstDate , men uteslut alla lastDate förutom den första (vanliga) instansen klockan 00:00 . Typiskt inte vad du vill. Med tanke på din formulering antar jag att det här är vad du verkligen vill ha:

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

① Detta inkluderar alla lastDate och effektivt. Du kan bara lägga till/subtrahera ett integer värde till/från ett date för att lägga till / subtrahera dagar . Den explicita casten till ::timestamp är valfritt eftersom datum automatiskt skulle tvingas fram i uttrycket. Men eftersom vi försöker reda ut förvirring här ...

Relaterat:

Bortsett från 1:

Nej. timestamp värden är inte formaterad, punkt. De är bara tidsstämpelvärden (internt lagrade som antalet mikrosekunder sedan epok). Visningen är helt skild från värdet och kan justeras på hundra och ett sätt utan att ändra värdet . Bli av med denna missuppfattning för att bättre förstå vad som händer. Se:

Bortsett från 2:

Om SQL BETWEENs underliga natur :

Bortsett från 3:

Tänk på lagliga identifierare med små bokstäver i Postgres. first_date istället för firstDate . Se:

Relaterat:



  1. alternativ till listagg i Oracle?

  2. Rails ActiveRecord hanterar en id-kolumn som inte är primärnyckeln

  3. Oracle-felmeddelandeinmatningsvärdet är inte tillräckligt långt

  4. Hur anger man det överordnade frågefältet från en underfråga i MySQL?