Cập nhật:
LATERAL
tham gia cho phép điều đó và đã được giới thiệu với Postgres 9.3. Chi tiết:
Lý do là trong thông báo lỗi. Một phần tử của FROM
danh sách không thể tham chiếu đến một phần tử khác của FROM
danh sách ngang hàng. Nó không hiển thị đối với một đồng nghiệp ở cùng cấp. Bạn có thể giải quyết vấn đề này bằng truy vấn con có tương quan :
SELECT *, (SELECT t FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
Rõ ràng, bạn không quan tâm hàng nào từ RP
bạn chọn từ một tập hợp các hàng gần bằng nhau, vì vậy tôi cũng làm như vậy.
Tuy nhiên, một biểu thức truy vấn con trong SELECT
danh sách chỉ có thể trả về một cột. Nếu bạn muốn nhiều hơn một hoặc tất cả các cột từ bảng RP
, sử dụng một cái gì đó giống như cấu trúc truy vấn con này:
Tôi giả sử sự tồn tại của khóa chính id
trong cả hai bảng.
SELECT id, t, (ra).*
FROM (
SELECT *, (SELECT rp FROM rp ORDER BY abs(rp.t - rq.t) LIMIT 1) AS ra
FROM rq
) x;
Các truy vấn phụ có liên quan bị tai tiếng vì hiệu suất kém . Loại truy vấn này - trong khi rõ ràng là tính toán những gì bạn muốn - sẽ hấp dẫn cụ thể là vì biểu thức rp.t - rq.t
không thể sử dụng một chỉ mục. Hiệu suất sẽ giảm mạnh với các bảng lớn hơn.
Truy vấn được viết lại này sẽ có thể sử dụng chỉ mục trên RP.t
, sẽ thực hiện nhiều nhanh hơn với các bảng lớn .
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;
Một lần nữa, nếu bạn muốn toàn bộ hàng:
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;
Lưu ý việc sử dụng dấu ngoặc đơn với các loại kết hợp ! Không có dấu ngoặc kép ở đây. Tìm hiểu thêm về điều đó trong sách hướng dẫn tại đây và tại đây .
Đã thử nghiệm với PostgreSQL 9.1. Demo trên sqlfiddle.