PostgreSQL 对视图的视图......这是正确的方法吗?

PostgreSQL views on views on views... is this the correct way?

我有一个 timescaledb 从两个能量传感器系列接收数据。一个的更新频率是 5',另一个是 10",具有不同的时间偏移量。计数器是累积的,我对聚合数据的 5' 时间样本很满意。我提供的解决方案利用了5 个视图:一个用于每个传感器系列以获取自然样本的差异,一个用于时间分桶,最后一个用于外部连接两个系列:

CREATE VIEW sampled_net_energy AS
    SELECT
      time AS "time",
      energy_t1_in + energy_t2_in - lag(energy_t1_in) OVER(ORDER BY time) - lag(energy_t2_in) OVER(ORDER BY time) as net_in,
      energy_t1_out + energy_t2_out - lag(energy_t1_out) OVER(ORDER BY time) - lag(energy_t2_out) OVER(ORDER BY time) as net_out
    FROM electricity
    ORDER BY 1;

CREATE VIEW bucketized_net_energy AS
    SELECT
      time_bucket('5 minutes', time) AS five_min,
      sum(net_in) as bkt_net_in,
      sum(net_out) as bkt_net_out
    FROM sampled_net_energy
    GROUP BY five_min
    ORDER BY 1;

CREATE VIEW sampled_solar_energy AS
    SELECT
      time AS "time",
      pvenergytotal-lag(pvenergytotal) OVER(ORDER BY time) as solar_in
    FROM t040504
    ORDER BY 1;

CREATE VIEW bucketized_solar_energy AS
    SELECT
      time_bucket('5 minutes', time) AS five_min,
      sum(solar_in) as bkt_solar_in
    FROM sampled_solar_energy
    GROUP BY five_min
    ORDER BY 1;

CREATE VIEW energy_balance AS
    SELECT
        a.five_min, bkt_net_in, bkt_net_out, bkt_solar_in
    FROM bucketized_net_energy a
    INNER JOIN bucketized_solar_energy b
    ON a.five_min = b.five_min
    ORDER BY 1;

我试图将每个家庭的两个视图总结为一个视图,但似乎我不能在聚合函数(求和)中使用滞后序列,而且我的 postgresql 知识也仅此而已。 我的问题是,如果房间里有任何 postgresql 专家:这是解决这个问题的正确方法吗?

更新:“我不能在聚合函数中使用滞后系列”是指当我 'select sum(a - lag(a)) as b' 时,我返回以下错误:'ERROR: aggregate function calls cannot contain window function calls'.

您的问题的解决方案是子查询。如果你做不到

SELECT sum(a - lag() OVER (...))
FROM ...
GROUP BY ...

改为这样做:

SELECT sum(b)
FROM (SELECT a - lag(a) OVER (...) AS b
      FROM ...) AS subq
GROUP BY ...

但我想提醒您不要在视图上定义视图。这没有技术问题,但它使维护和调试您的查询变得非常困难。那是因为在实际查询中,所有的视图都被解决了,你最终会得到一个相当复杂的难以理解的查询。特别是,您 运行 有加入额外不必要的 table 的风险,或者加入相同的 table 两次,因为它出现在两个视图中。我曾多次被要求调整此类查询,因为性能很差,而且我常常不得不放弃,因为巴比伦塔的观点对我简单的大脑来说太多了。