PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie schreibe ich eine Funktion in plpgsql, die ein Datum mit einem Zeitstempel ohne Zeitzone vergleicht?

Was Pavel gesagt hat.

Darüber hinaus deutet zunächst nichts auf die Notwendigkeit von PL/pgSQL hin. Ein einfaches (vorbereitetes) SELECT Aussage kann es tun. Oder eine SQL-Funktion, wenn Sie sie in der Datenbank beibehalten möchten. Siehe:

Und bezüglich:

Inklusive/exklusive Ober-/Untergrenze genau definieren um überraschende Eckfallergebnisse zu vermeiden. Beim Vergleich eines timestamp Spalte zu einem date , wird letzterer auf den Zeitstempel gezwungen, der die erste Instanz des Tages angibt:YYYY.MM.DD 00:00:00 .

Ihre Abfrage lautet:

measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... was das gesamte firstDate beinhalten würde , aber alle lastDate ausschließen mit Ausnahme der ersten (gemeinsamen) Instanz um 00:00 . Normalerweise nicht das, was Sie wollen. Angesichts Ihrer Formulierung nehme ich an, dass Sie das wirklich wollen:

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

① Dies umfasst alles von lastDate , und effizient. Sie können einfach eine integer Wert bis / von einem date zum Addieren / Subtrahieren von Tagen . Die explizite Umwandlung in ::timestamp ist optional, da das Datum im Ausdruck automatisch erzwungen würde. Aber da wir hier versuchen, Verwirrung zu beseitigen ...

Verwandte:

Neben 1:

Nr. timestamp Werte sind nicht formatiert, Punkt. Sie sind nur Zeitstempelwerte (intern als Anzahl von Mikrosekunden seit der Epoche gespeichert). Die Anzeige ist vollständig vom Wert getrennt und kann auf hundertundeine Weise angepasst werden, ohne den Wert zu ändern . Beseitigen Sie dieses Missverständnis, um besser zu verstehen, was vor sich geht. Siehe:

Neben 2:

Über die hinterhältige Natur von SQL BETWEEN :

Neben 3:

Berücksichtigen Sie legale, kleingeschriebene Bezeichner in Postgres. first_date statt firstDate . Siehe:

Verwandte: