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

tham chiếu không hợp lệ đến mục nhập mệnh đề FROM cho bảng trong truy vấn Postgres

Giải thích cho lỗi

Nguyên nhân ngay lập tức cho thông báo lỗi là bất kỳ JOIN rõ ràng nào liên kết mạnh hơn dấu phẩy (, ) tương đương với CROSS JOIN , nhưng ( theo tài liệu ):

In đậm nhấn mạnh của tôi.
Đây là nguyên nhân gây ra lỗi của bạn. Bạn có thể sửa nó:

FROM  appointment_intakes
CROSS JOIN LATERAL jsonb_object_keys(data #> '{products}') keys
INNER JOIN appointment_intake_users ON ...

Nhưng đó không phải là vấn đề duy nhất. Hãy tiếp tục đọc.

Người ta có thể tranh luận rằng Postgres nên thấy rằng LATERAL chỉ có ý nghĩa liên quan đến bảng bên trái. Nhưng không phải vậy.

Giả định

Tôi đã thêm bí danh bảng và tất cả các tên cột đủ điều kiện bảng như nghi ngờ. Trong khi thực hiện, tôi đã đơn giản hóa các tham chiếu JSON và cắt bớt một số nhiễu. Truy vấn này vẫn không chính xác :

SELECT i.data ->> 'id'          AS id,
       i.data ->> 'name'        AS name,
       i.data ->> 'curator'     AS curator,
       i.data ->  '$isValid'    AS "$isValid",
       i.data ->  'customer'    AS customer,
       i.data ->  '$createdTS'  AS "$createdTS",
       i.data ->  '$updatedTS'  AS "$updatedTS",
       i.data ->  '$isComplete' AS "$isComplete",
       count(k.keys)::numeric   AS "numProducts",
       u.created_at
FROM   appointment_intakes i
     , jsonb_object_keys(i.data -> 'products') AS k(keys)
JOIN   appointment_intake_users u ON u.appointment_intake_id = i.id
#{where_clause}
GROUP  BY i.id

Truy vấn thô

Dựa trên những điều trên và một số giả định khác, giải pháp có thể là thực hiện đếm trong một truy vấn con:

SELECT i.data ->> 'id'          AS id,
       i.data ->> 'name'        AS name,
       i.data ->> 'curator'     AS curator,
       i.data ->  '$isValid'    AS "$isValid",
       i.data ->  'customer'    AS customer,
       i.data ->  '$createdTS'  AS "$createdTS",
       i.data ->  '$updatedTS'  AS "$updatedTS",
       i.data ->  '$isComplete' AS "$isComplete",
       (SELECT count(*)::numeric
        FROM   jsonb_object_keys(i.data -> 'products')) AS "numProducts",
       min(u.created_at)        AS created_at
FROM   appointment_intakes i
JOIN   appointment_intake_users u ON u.appointment_intake_id = i.id
--     #{where_clause}
GROUP  BY i.id;

Vì bạn chỉ cần số lượng, nên tôi đã chuyển đổi LATERAL của bạn nối vào một truy vấn con tương quan, do đó tránh được các vấn đề khác nhau phát sinh từ nhiều phép nối 1:n kết hợp với nhau. Thêm:

Bạn cần để thoát khỏi số nhận dạng đúng cách, hãy sử dụng câu lệnh đã soạn sẵn và chuyển giá trị như các giá trị. Không nối các giá trị vào chuỗi truy vấn. Đó là lời mời cho các lỗi ngẫu nhiên hoặc Chèn SQL các cuộc tấn công. Ví dụ gần đây cho PHP:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL và Dữ liệu tuần tự

  2. Bắt đầu từ một ngày trong PostgreSQL

  3. Tham số psql tham chiếu bên trong khối ẩn danh PL / pgSQL

  4. Ràng buộc duy nhất với các điều kiện trong MYSQL

  5. Postgres SAO CHÉP ĐẾN / TỪ MỘT TẬP TIN với tư cách không phải là người dùng cấp cao