PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

LỖI:truy vấn con trong FROM không thể tham chiếu đến các quan hệ khác có cùng cấp độ truy vấn

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 tại đây .

Đã thử nghiệm với PostgreSQL 9.1. Demo trên sqlfiddle.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cải thiện hiệu suất truy vấn PostgreSQL khi rời tham gia cho 100 triệu dữ liệu

  2. Rails 3, will_paginate, ngẫu nhiên, các bản ghi lặp lại, Postgres, setseed thất bại

  3. Tổng hợp (x, y) các đám mây điểm tọa độ trong PostgreSQL

  4. Trả lại một truy vấn từ một hàm?

  5. Chọn kiểu dữ liệu của trường trong postgres