Además, nada indica la necesidad de PL/pgSQL para empezar. Un simple (preparado) SELECT
declaración puede hacerlo. O una función SQL, si desea conservarla en la base de datos. Ver:
Y sobre:
Definir límite superior / inferior inclusivo / exclusivo precisamente para evitar resultados sorprendentes en casos de esquina. Al comparar una timestamp
columna a una date
, este último está obligado a la marca de tiempo que significa la primera instancia del día:YYYY.MM.DD 00:00:00
.
Tu consulta dice:
measurement_timestamp <= lastDate AND measurement_timestamp >= firstDate
... que incluiría todo firstDate
, pero excluye todo lastDate
excepto por la primera instancia (común) a las 00:00 . Normalmente no es lo que quieres. Dada su formulación, supongo que esto es lo que realmente quiere:
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$;
① Esto incluye todo lastDate
, y eficientemente. Simplemente puede sumar/restar un integer
valor a/desde una date
para sumar/restar días
. La conversión explícita a ::timestamp
es opcional ya que la fecha se coaccionaría en la expresión automáticamente. Pero como estamos tratando de aclarar la confusión aquí...
Relacionado:
Aparte 1:
No. timestamp
los valores son no formateado, punto. Son solo valores de marca de tiempo (almacenados internamente como el número de microsegundos desde la época). La pantalla está completamente separada del valor y se puede ajustar de ciento una maneras sin cambiar el valor . Deshazte de este concepto erróneo para entender mejor lo que está pasando. Ver:
Aparte 2:
Acerca de la naturaleza tortuosa de SQL BETWEEN
:
Aparte 3:
Considere los identificadores legales en minúsculas en Postgres. first_date
en lugar de firstDate
. Ver:
Relacionado:
- Función de PostgreSQL que devuelve un cubo de datos
- Postgresql tratando de usar el formato de ejecución en una función pero obteniendo un error de columna no encontrada al dar formato de cadena en coalesce