Mise à jour :
LATERAL
les jointures le permettent et ont été introduites avec Postgres 9.3. Détails :
La raison est dans le message d'erreur. Un élément du FROM
la liste ne peut pas faire référence à un autre élément du FROM
liste au même niveau. Il n'est pas visible pour un pair au même niveau. Vous pouvez résoudre ce problème avec une sous-requête corrélée :
SELECT *, (SELECT t FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
De toute évidence, vous ne vous souciez pas de la ligne de RP
vous choisissez parmi un ensemble de lignes également proches, donc je fais de même.
Cependant, une expression de sous-requête dans le SELECT
la liste ne peut en renvoyer qu'un colonne. Si vous voulez plus d'une ou toutes les colonnes de la table RP
, utilisez quelque chose comme cette construction de sous-requête :
Je suppose l'existence d'une clé primaire id
dans les deux tableaux.
SELECT id, t, (ra).*
FROM (
SELECT *, (SELECT rp FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
) x;
Les sous-requêtes corrélées sont tristement célèbres pour leurs mauvaises performances . Ce genre de requête - tout en calculant évidemment ce que vous voulez - va crainer notamment parce que l'expression rp.t - rq.t
ne peut pas utiliser un index. Les performances se détérioreront considérablement avec des tables plus grandes.
Cette requête réécrite devrait pouvoir utiliser un index sur RP.t
, qui devrait être beaucoup performant plus rapide avec de grandes 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;
Encore une fois, si vous voulez toute la ligne :
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;
Notez l'utilisation de parenthèses avec les types composites ! Aucune parenthèse n'est redondante ici. Plus d'informations à ce sujet dans le manuel ici et ici .
Testé avec PostgreSQL 9.1. Démo sur sqlfiddle.