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

RETURNING gây ra lỗi:thiếu mục nhập mệnh đề FROM cho bảng

Sự thật, như đã được lưu ý, rằng RETURNING mệnh đề của một INSERT chỉ nhìn thấy hàng được chèn. Cụ thể hơn, trích dẫn sách hướng dẫn tại đây :

In đậm nhấn mạnh của tôi.
Vì vậy, không có gì ngăn bạn thêm truy vấn con tương quan đến RETURNING danh sách:

INSERT INTO employees.password_resets AS ep
       (empl_pwd_reset_uuid                  , empl_user_pvt_uuid                    , t_valid                     , for_empl_user_pvt_uuid, token)
SELECT 'f70a0346-a077-11eb-bd1a-aaaaaaaaaaaa', '6efc2b7a-f27e-11ea-b66c-de1c405de048', '2021-04-18 19:57:47.111365', eu.empl_user_pvt_uuid , '19d65aea-7c4a-41bc-b580-9d047f1503e6'
FROM   employees.users eu
WHERE  empl_user_pub_uuid = 'e2bb39f1f28011eab66c63cb4d9c7a34'
RETURNING for_empl_user_pvt_uuid AS empl_user_pvt_uuid  -- alias to meet your org. query
        , (SELECT email
           FROM   employees.emails
           WHERE  empl_user_pvt_uuid = ep.empl_user_pvt_uuid
           ORDER  BY t DESC  -- NULLS LAST ?
           LIMIT  1
          ) AS email
        , (SELECT name_first
           FROM   employees.profiles
           WHERE  empl_user_pvt_uuid = ep.empl_user_pvt_uuid
           -- ORDER  BY ???
           LIMIT  1
          ) AS name_first;

Điều này cũng hiệu quả hơn nhiều so với truy vấn bạn có (hoặc những gì đã được đề xuất) vì nhiều lý do.

Thêm vào đó, có thể là quan trọng nhất, điều này chính xác . Chúng tôi sử dụng dữ liệu từ hàng đã thực sự được chèn - sau chèn nó. (Xem phần trích dẫn ở trên cùng!) Sau khi các giá trị mặc định có thể có, các trình kích hoạt hoặc quy tắc đã được áp dụng. Chúng tôi có thể chắc chắn rằng những gì chúng tôi thấy là những gì thực sự có trong cơ sở dữ liệu (hiện tại).

Bạn không có ORDER BY cho profiles.name_first . Điều đó không đúng. Hoặc chỉ có một hàng đủ điều kiện, thì chúng ta không cần DISTINCT cũng không phải LIMIT 1 . Hoặc có thể có nhiều, thì chúng ta cũng cần một ORDER BY xác định để có được kết quả xác định.

Và nếu emails.t có thể là NULL, bạn sẽ muốn thêm NULLS LAST trong ORDER BY mệnh đề. Xem:

Chỉ mục

Lý tưởng nhất là bạn có các chỉ mục đa cột này (với các cột theo thứ tự này):

  • users (empl_user_pub_uuid, empl_user_pvt_uuid)
  • emails (empl_user_pvt_uuid, email)
  • profiles (empl_user_pvt_uuid, name_first)

Sau đó, nếu các bảng được hút bụi đủ, bạn sẽ nhận được ba lần quét chỉ mục và toàn bộ hoạt động sẽ nhanh chóng sáng sủa.

Nhận trước INSERT giá trị?

Nếu bạn thực sự muốn điều đó (mà tôi không nghĩ bạn làm vậy), hãy xem xét:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chuyển mảng thẻ cho một hàm plpgsql và sử dụng nó trong điều kiện WHERE

  2. Để chuyển đổi từ mảng Python sang PostgreSQL một cách nhanh chóng?

  3. Hướng dẫn về Pgpool cho PostgreSQL:Phần thứ hai

  4. Rails 3, Heroku:Taps Server Error:PGError:ERROR:chuỗi byte không hợp lệ để mã hóa UTF8:0xba

  5. Làm thế nào để nhóm và đếm theo ngày trong Rails ở Postgres?