sql >> Databáze >  >> RDS >> PostgreSQL

Jak napíšu funkci v plpgsql, která porovnává datum s časovým razítkem bez časového pásma?

Co řekl Pavel.

A co víc, nic nenaznačuje, že je pro začátek potřeba PL/pgSQL. Prostý (připravený) SELECT prohlášení to dokáže. Nebo funkce SQL, pokud ji chcete ponechat v databázi. Viz:

A ohledně:

Definujte inkluzivní / exkluzivní horní / dolní mez přesně abyste se vyhnuli překvapivým výsledkům v rohových případech. Při porovnávání timestamp sloupec na date , druhý je vynucen na časové razítko označující první výskyt dne:YYYY.MM.DD 00:00:00 .

Váš dotaz zní:

measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... který by zahrnoval všechny firstDate , ale vyloučit všechny položky lastDate kromě první (běžné) instance v 00:00 . Obvykle ne to, co chcete. Vzhledem k vaší formulaci předpokládám, že toto opravdu chcete:

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

① To zahrnuje všechny lastDate a efektivně. Stačí přičíst/odečíst integer hodnotu do / od date přidat/odečíst dny . Explicitní přetypování na ::timestamp je nepovinné, protože datum by bylo ve výrazu automaticky vynuceno. Ale protože se zde snažíme vyjasnit zmatek ...

Související:

Stranou 1:

Č. timestamp hodnoty není formátováno, tečka. Jsou to pouze hodnoty časového razítka (interně uložené jako počet mikrosekund od epochy). Displej je zcela oddělený od hodnoty a lze jej upravit sto a jedním způsobem bez změny hodnoty . Zbavte se této mylné představy, abyste lépe pochopili, co se děje. Viz:

Stranou 2:

O nevyzpytatelné povaze SQL BETWEEN :

Stranou 3:

Zvažte legální identifikátory s malými písmeny v Postgresu. first_date místo firstDate . Viz:

Související:



  1. Funkce MySQL CHAR() a výstup UTF8?

  2. MySQL dotaz Select, SUM, LEFT JOIN

  3. Oprava „SQL Server zablokoval přístup k STATEMENT ‚OpenRowset/OpenDatasource‘ komponenty ‚Ad Hoc Distributed Queries‘

  4. ORACLE – najděte konkrétní výsledek uvnitř SMYČKY (NEBO PODOBNÉ)