更新:
LATERAL
結合はそれを可能にし、Postgres9.3で導入されました。詳細:
理由はエラーメッセージにあります。 FROM
の1つの要素 リストはFROM
の別の要素を参照できません 同じレベルのリスト。同じレベルのピアには表示されません。相関サブクエリを使用してこれを解決できます。 :
SELECT *, (SELECT t FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
明らかに、RP
のどの行を気にする必要はありません。 等しく近い行のセットから選択するので、私も同じことをします。
ただし、SELECT
のサブクエリ式 リストは1つしか返すことができません 桁。テーブルの複数またはすべての列が必要な場合RP
、次のサブクエリ構造のようなものを使用します。
主キーid
が存在すると想定します。 両方のテーブルで。
SELECT id, t, (ra).*
FROM (
SELECT *, (SELECT rp FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
) x;
相関するサブクエリは、パフォーマンスの低下で有名です 。この種のクエリは、明らかに必要なものを計算しますが、吸います 特に、式rp.t - rq.t
インデックスは使用できません。テーブルが大きくなると、パフォーマンスが大幅に低下します。
この書き直されたクエリは、RP.t
のインデックスを利用できる必要があります。 、多くを実行する必要があります 大きなテーブルでより速く 。
WITH x AS (
SELECT *
,(SELECT t
FROM rp
WHERE rp.t < rq.t
ORDER BY rp.t DESC
LIMIT 1) AS t_pre
,(SELECT t
FROM rp
WHERE rp.t >= rq.t
ORDER BY rp.t
LIMIT 1) AS t_post
FROM rq
)
SELECT id, t
,CASE WHEN (t_post - t) < (t - t_pre)
THEN t_post
ELSE COALESCE(t_pre, t_post) END AS ra
FROM x;
繰り返しますが、行全体が必要な場合:
WITH x AS (
SELECT *
,(SELECT rp
FROM rp
WHERE rp.t < rq.t
ORDER BY rp.t DESC
LIMIT 1) AS t_pre
,(SELECT rp
FROM rp
WHERE rp.t >= rq.t
ORDER BY rp.t
LIMIT 1) AS t_post
FROM rq
), y AS (
SELECT id, t
,CASE WHEN ((t_post).t - t) < (t - (t_pre).t)
THEN t_post
ELSE COALESCE(t_pre, t_post) END AS ra
FROM x
)
SELECT id AS rq_id, t AS rq_t, (ra).*
FROM y
ORDER BY 2;
複合型での括弧の使用に注意してください !ここでは冗長なパレンはありません。詳細については、マニュアルこちら
をご覧ください。 および
PostgreSQL9.1でテスト済み。 sqlfiddleのデモ