Update:
LATERAL
joins allow this and were introduced with Postgres 9.3. Details:
The reason is in the error message. One element of the FROM
list cannot refer to another element of the FROM
list at the same level. It is not displayed for the peer at the same level. You can solve this with a correlated subquery :
SELECT *, (SELECT t FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra FROM rq
Obviously, you don’t care which line from RP
you choose from a set of equally close lines, so I do the same.
However, a subquery expression in a SELECT
list can return only one column. If you want to have more than one or all columns from an RP
table, use something like this subquery construct:
I assume the existence of the id
primary key in both tables.
SELECT id, t, (ra).* FROM ( SELECT *, (SELECT rp FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra FROM rq ) x;
Related subqueries are notorious for poor performance . This kind of query, in which, obviously, calculates what you want, will suck, in particular, because the expression rp.t - rq.t
cannot use the index. Efficiency will drop dramatically with large tables.
This rewritten query should be able to use an index on RP.t
, which should run much faster with large tables .
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;
Again, if you want the whole line:
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;
Pay attention to the use of parentheses with compound types ! There is no superfluous. More about this in the manual here and here .
Tested with PostgreSQL 9.1. Demo on sqlfiddle.