Aktualisierung:
LATERAL
Joins erlauben dies und wurden mit Postgres 9.3 eingeführt. Einzelheiten:
Der Grund steht in der Fehlermeldung. Ein Element des FROM
list kann nicht auf ein anderes Element von FROM
verweisen Liste auf der gleichen Ebene. Es ist für einen Peer auf derselben Ebene nicht sichtbar. Sie könnten dies mit einer korrelierten Unterabfrage lösen :
SELECT *, (SELECT t FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
Offensichtlich ist es Ihnen egal, welche Zeile aus RP
stammt Sie wählen aus einer Reihe gleich enger Reihen aus, also mache ich dasselbe.
Allerdings ein Unterabfrageausdruck im SELECT
list kann nur eine zurückgeben Säule. Wenn Sie mehr als eine oder alle Spalten aus der Tabelle RP
wünschen , verwenden Sie so etwas wie dieses Unterabfragekonstrukt:
Ich gehe davon aus, dass ein Primärschlüssel id
existiert in beiden Tabellen.
SELECT id, t, (ra).*
FROM (
SELECT *, (SELECT rp FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
) x;
Korrelierte Unterabfragen sind berüchtigt für schlechte Leistung . Diese Art von Abfrage - während sie offensichtlich berechnet, was Sie wollen - wird beschissen sein insbesondere, weil der Ausdruck rp.t - rq.t
kann keinen Index verwenden. Bei größeren Tabellen verschlechtert sich die Leistung drastisch.
Diese umgeschriebene Abfrage sollte in der Lage sein, einen Index auf RP.t
zu verwenden , die viel leisten sollte schneller mit großen Tischen .
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;
Nochmals, wenn Sie die ganze Reihe wollen:
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;
Beachten Sie die Verwendung von Klammern bei zusammengesetzten Typen ! Hier ist kein Elternteil überflüssig. Mehr dazu im Handbuch hier und hier .
Getestet mit PostgreSQL 9.1. Demo auf sqlfiddle.