使用时区选择每日最后一次非空值

时间:2016-09-28 14:22:40

标签: postgresql

我有许多传感器提供的数据集合,需要获取每个传感器在特定时区的最后一天值。

每台设备都位于GEO位置,因此我需要相应的日期。

以下是涉及的表格:

.find_in_batches

查询:

CREATE TABLE public.dt_weight(
  hive character(20) NOT NULL,
  hiveconnection integer,
  instant timestamp with time zone NOT NULL,
  weight integer,
  optweight integer,
  CONSTRAINT dt_weight_pkey PRIMARY KEY (hive, instant)
)

和结果(蜂巢,时刻,最后):

SELECT w1.*
    FROM dt_weight w1
    JOIN (
        SELECT hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') AS moment, 
            MAX(instant) AT TIME ZONE 'pst' AS last 
        FROM dt_weight 
        WHERE weight IS NOT NULL AND hive = '002C0055700833024E45' 
        GROUP BY DATE_TRUNC('day', instant AT TIME ZONE 'pst'), hive
    ) w2
    on (w1.instant = w2.last AND w1.hive=w2.hive)
WHERE w1.hive = '002C0055700833024E45' 
ORDER BY moment

时刻和最后时间以时间戳没有时区返回,并且缺少许多记录!单独尝试子查询我得到更多的值:

"002C0055700833024E45";932890;"2015-11-23 23:55:42+01";27800;
"002C0055700833024E45";933006;"2015-11-25 23:56:02+01";27770;
"002C0055700833024E45";933065;"2015-11-26 23:56:22+01";27610;

第18天至第22天和第24天没有出现。为什么?!?我的客户时区是CEST。需要提一下,这个查询是一个更大的计划。

为了完整性,这里有一些源数据:

SELECT hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') AS moment, 
    MAX(instant) AT TIME ZONE 'pst' AS last 
FROM dt_weight 
WHERE weight IS NOT NULL AND hive = '002C0055700833024E45' 
GROUP BY DATE_TRUNC('day', instant AT TIME ZONE 'pst'), hive
ORDER BY last

"002C0055700833024E45";"2015-11-18 00:00:00";"2015-11-18 23:57:17"
"002C0055700833024E45";"2015-11-19 00:00:00";"2015-11-19 23:58:12"
"002C0055700833024E45";"2015-11-20 00:00:00";"2015-11-20 23:52:12"
"002C0055700833024E45";"2015-11-21 00:00:00";"2015-11-21 23:53:03"
"002C0055700833024E45";"2015-11-22 00:00:00";"2015-11-22 23:55:47"
"002C0055700833024E45";"2015-11-23 00:00:00";"2015-11-23 23:55:42"
"002C0055700833024E45";"2015-11-24 00:00:00";"2015-11-24 23:56:02"
"002C0055700833024E45";"2015-11-25 00:00:00";"2015-11-25 23:56:02"
"002C0055700833024E45";"2015-11-26 00:00:00";"2015-11-26 23:56:22"

1 个答案:

答案 0 :(得分:1)

试试这个:

SELECT
    DISTINCT ON (hive, moment)
    *, DATE_TRUNC('day', instant AT TIME ZONE 'pst') AS moment
FROM dt_weight
ORDER BY hive, moment DESC, instant DESC;

它使用DISTINCT ON仅保留hive和日期的每个组合的第一行。为了确保我们保留的第一行也是最新的一行,我们还按相反的时间顺序排序。