在连接中推送动态参数 - 无法从查询的这一部分引用

时间:2016-10-01 10:01:22

标签: postgresql

一个表包含我需要在其他连接中使用的timezoneID,但是我得到无法从查询的这一部分引用错误。 有没有办法解决这个问题?

查询是以编程方式生成的,所以在最糟糕的情况下,我可以递归循环所有ID,但是如果可能的话,我希望实现一个视图或编译的东西,并使用比java更多的SQL。

以下是查询(与this question相关):

WITH h AS (
    SELECT id, timez, 
        TIMESTAMP WITHOUT TIME ZONE '2016-05-1' AT TIME ZONE timez AS start,
        TIMESTAMP WITHOUT TIME ZONE '2016-05-5 23:59:59' AT TIME ZONE timez AS end,
        DATE_TRUNC('DAY', generate_series(
            TIMESTAMP WITHOUT TIME ZONE '2016-05-1' AT TIME ZONE timez, 
            TIMESTAMP WITHOUT TIME ZONE '2016-05-1' AT TIME ZONE timez + INTERVAL '4 DAYS',
            '1 day'
        ) AT TIME ZONE timez) AS moment 
    FROM hives
)
SELECT  id, h.moment, timez, t.internal_avg, t.external_min, t.external_max, w1.weight, w2.optweight
FROM h
    LEFT JOIN (
        SELECT hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') AS moment, 
            AVG(internal)::integer AS internal_avg, MIN(external)::integer AS external_min, 
            MAX(external)::integer AS external_max
        FROM dt_temperature
        GROUP BY hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst')
    ) AS t ON (id=t.hive AND h.moment=t.moment)
    LEFT JOIN (
        SELECT DISTINCT ON (hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst')) 
            hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') AS moment, weight
        FROM dt_weight
        WHERE weight IS NOT NULL
        ORDER BY hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') DESC, instant DESC
    ) AS w1 ON (id=w1.hive AND h.moment=w1.moment)
    LEFT JOIN (
        SELECT DISTINCT ON (hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst')) 
            hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') AS moment, optweight
        FROM dt_weight
        WHERE optweight IS NOT NULL
        ORDER BY hive, DATE_TRUNC('day', instant AT TIME ZONE 'pst') DESC, instant DESC
    ) AS w2 ON (id=w2.hive AND h.moment=w2.moment)

WHERE id = '002C0055700833024E45' 
ORDER BY h.moment

我想使用 h.timez 字段,而不是在任何地方重复'pst'

****编辑 - @a_horse_with_no_name ****

建议的解决方案
LEFT JOIN LATERAL(
    SELECT hive, DATE_TRUNC('day', instant AT TIME ZONE timez) AS moment, 
        AVG(internal)::integer AS internal_avg, MIN(external)::integer AS external_min, 
        MAX(external)::integer AS external_max
    FROM dt_temperature
    WHERE instant >= start AND instant <= "end"
    GROUP BY hive, DATE_TRUNC('day', instant AT TIME ZONE timez)
) AS t ON (id=t.hive AND h.moment=t.moment)

使用LATERAL可以传递 timez 参数以及开始结束,从而减少JOINS处理的记录数量( 即时当然已编入索引)。 查询运行时间从243降低到21毫秒

0 个答案:

没有答案