PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

RETURNING причинява грешка:липсващ запис от клауза FROM за таблица

Вярно е, както беше отбелязано, че RETURNING клауза на INSERT вижда само вмъкнатия ред. По-конкретно, цитирайки ръководството тук :

Удебелен акцентът е мой.
Така че нищо не ви пречи да добавите корелирана подзаявка към RETURNING списък:

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;

Това също е много по-ефективно отколкото заявката, която сте имали (или това, което е било предложено) поради множество причини.

Освен това, вероятно най-важното, това е правилно . Ние използваме данни от реда, който действително е бил вмъкнат -след поставяйки го. (Вижте цитата в горната част!) След като бъдат приложени възможните стойности по подразбиране, задействания или правила. Можем да сме сигурни, че това, което виждаме, е това, което действително е в базата данни (в момента).

Нямате ORDER BY за profiles.name_first . Това не е правилно. Или има само един квалифициращ ред, тогава нямаме нужда от DISTINCT нито LIMIT 1 . Или може да има няколко, тогава се нуждаем и от детерминистичен ORDER BY за да получите детерминистичен резултат.

И ако emails.t може да бъде NULL, ще искате да добавите NULLS LAST в ORDER BY клауза. Вижте:

Индекси

В идеалния случай имате тези многоколонни индекси (с колони в този ред):

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

След това, ако масите са достатъчно вакуумирани, получавате три сканирания само за индекси и цялата операция е светкавична.

Вземете предварително INSERT ценности?

Ако наистина искате това (което не мисля, че искате), помислете за:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Heroku Postgres:Тази връзка е затворена

  2. Връщане на групиран списък с поява с помощта на Rails и PostgreSQL

  3. Застой в PostgreSQL при изпълнение на UPDATE

  4. Как да посочите текущата работеща база данни за скрипта за инициализация на контейнер за докер постгрес?

  5. Декларираният размер на полето varchar има ли някакво влияние в PostgreSQL?