Je pravda, jak bylo uvedeno, že RETURNING
klauzule INSERT
vidí pouze vložený řádek. Přesněji řečeno, cituji manuál zde :
Tučné důraz můj.
Nic vám tedy nebrání přidat korelovaný poddotaz do RETURNING
seznam:
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;
To je také mnohem efektivnější než dotaz, který jste měli (nebo to, co bylo navrženo) z několika důvodů.
-
Poddotazy
ee
nespouštíme aep
přes všechny řádky tabulekemployees.emails
aemployees.profiles
. To by bylo efektivní, kdybychom potřebovali hlavní části těchto tabulek, ale z každé načteme pouze jeden řádek zájmu. S vhodnými indexy je korelovaný poddotaz mnohem efektivnější. Viz: -
Nepřipočítáváme režii jednoho nebo více CTE.
-
Další data načítáme až po úspěšné
INSERT
, takže se neztrácí čas, pokud vložka z jakéhokoli důvodu neprošla. (Viz citát nahoře!)
Navíc, což je možná nejdůležitější, je to správné . Použijeme data z řádku, který byl skutečně vložen – po jeho vložení. (Viz citace nahoře!) Po použití možných výchozích hodnot, spouštěčů nebo pravidel. Můžeme si být jisti, že to, co vidíme, je to, co je skutečně v databázi (aktuálně).
Nemáte žádné ORDER BY
pro profiles.name_first
. To není správné. Buď je pouze jeden kvalifikační řádek, pak nepotřebujeme žádný DISTINCT
ani LIMIT 1
. Nebo jich může být více, pak potřebujeme také deterministický ORDER BY
získat deterministický výsledek.
A pokud emails.t
může být NULL, budete chtít přidat NULLS LAST
v ORDER BY
doložka. Viz:
Indexy
V ideálním případě máte tyto vícesloupcové indexy (se sloupci v tomto pořadí):
users (empl_user_pub_uuid, empl_user_pvt_uuid)
emails (empl_user_pvt_uuid, email)
profiles (empl_user_pvt_uuid, name_first)
Pokud jsou pak stoly dostatečně vysáté, získáte tři skenování pouze s indexem a celá operace se zrychlí.
Získejte před-INSERT
hodnoty?
Pokud to opravdu chcete (což si nemyslím, že chcete), zvažte: