Det är sant, som har noterats, att RETURNING
sats av en INSERT
ser bara den infogade raden. Mer specifikt, citerar manualen här a> :
Fet betoning min.
Så inget hindrar dig från att lägga till en korrelerad underfråga till RETURNING
lista:
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;
Detta är också mycket effektivare än den fråga du hade (eller vad som föreslagits) av flera skäl.
-
Vi kör inte underfrågorna
ee
ochep
över alla rader i tabellernaemployees.emails
ochemployees.profiles
. Det skulle vara effektivt om vi behövde större delar av dessa tabeller, men vi hämtar bara en enda rad med intresse från varje. Med lämpliga index är en korrelerad underfråga mycket effektivare för detta. Se: -
Vi lägger inte till overhead för en eller flera CTE.
-
Vi hämtar bara ytterligare data efter en lyckad
INSERT
, så ingen tid går till spillo om insatsen av någon anledning inte gick igenom. (Se citat överst!)
Plus, kanske viktigast, detta är korrekt . Vi använder data från raden som faktiskt har infogats - efter sätter in den. (Se citat överst!) Efter möjliga standardvärden har triggers eller regler tillämpats. Vi kan vara säkra på att det vi ser är det som faktiskt finns i databasen (för närvarande).
Du har ingen ORDER BY
för profiles.name_first
. Det är inte rätt. Antingen finns det bara en kvalificerande rad, då behöver vi ingen DISTINCT
inte heller LIMIT 1
. Eller så kan det vara flera, då behöver vi också en deterministisk ORDER BY
för att få ett deterministiskt resultat.
Och om emails.t
kan vara NULL, vill du lägga till NULLS LAST
i ORDER BY
klausul. Se:
Index
Helst har du dessa flerkolumnindex (med kolumner i denna ordning):
users (empl_user_pub_uuid, empl_user_pvt_uuid)
emails (empl_user_pvt_uuid, email)
profiles (empl_user_pvt_uuid, name_first)
Sedan, om borden är tillräckligt sugna, får du tre index-skanningar och hela operationen blir snabbare.
Hämta pre-INSERT
värden?
Om du verkligen vill det (vilket jag inte tror att du gör), överväg: