PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como escrevo uma função no plpgsql que compara uma data com um carimbo de data/hora sem fuso horário?


O que Pavel disse.

Além do mais, nada indica a necessidade de PL/pgSQL para começar. Um SELECT simples (preparado) declaração pode fazê-lo. Ou uma função SQL, se você quiser mantê-la no banco de dados. Ver:

E sobre:

Definir limite superior/inferior inclusivo/exclusivo precisamente para evitar resultados surpreendentes de casos de canto. Ao comparar um timestamp coluna para uma date , o último é forçado para o timestamp que significa a primeira instância do dia:YYYY.MM.DD 00:00:00 .

Sua consulta diz:
measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate

... que incluiria todo o firstDate , mas excluir todos os lastDate exceto para a primeira instância (comum) às 00:00 . Normalmente não é o que você quer. Dada a sua formulação, suponho que é isso que você realmente quer:
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$;

① Isso inclui todo o lastDate , e com eficiência. Você pode apenas adicionar/subtrair um integer valor para/de uma date para adicionar/subtrair dias . A conversão explícita para ::timestamp é opcional, pois a data seria forçada na expressão automaticamente. Mas já que estamos tentando esclarecer a confusão aqui ...

Relacionado:

Além 1:

Não. timestamp os valores não formatado, ponto. Eles são apenas valores de timestamp (armazenados internamente como o número de microssegundos desde a época). A exibição é completamente separada do valor e pode ser ajustada de mil e uma maneiras sem alterar o valor . Livre-se desse equívoco para entender melhor o que está acontecendo. Ver:

Além 2:

Sobre a natureza desonesta do SQL BETWEEN :

Além 3:

Considere identificadores legais em letras minúsculas no Postgres. first_date em vez de firstDate . Ver:

Relacionado: