sql >> Database >  >> RDS >> PostgreSQL

RETURNING veroorzaakt fout:ontbrekende FROM-clausule voor tabel

Het is waar, zoals is opgemerkt, dat de RETURNING clausule van een INSERT ziet alleen de ingevoegde rij. Meer specifiek, de handleiding hier citerend :

Vet nadruk van mij.
Dus niets weerhoudt u ervan een gecorreleerde subquery toe te voegen naar de RETURNING lijst:

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;

Dit is ook veel efficiënter dan de vraag die je had (of wat werd voorgesteld) om meerdere redenen.

En, misschien wel het belangrijkste, dit is correct . We gebruiken gegevens uit de rij die daadwerkelijk is ingevoegd - na het invoegen. (Zie citaat bovenaan!) Nadat eventuele standaardwaarden, triggers of regels zijn toegepast. We kunnen er zeker van zijn dat wat we zien is wat er daadwerkelijk in de database staat (momenteel).

U heeft geen ORDER BY voor profiles.name_first . Dat klopt niet. Ofwel is er maar één kwalificatierij, dan hebben we geen DISTINCT . nodig noch LIMIT 1 . Of er kunnen er meerdere zijn, dan hebben we ook een deterministische ORDER BY nodig om een ​​deterministisch resultaat te krijgen.

En als emails.t kan NULL zijn, voeg dan NULLS LAST toe in de ORDER BY clausule. Zie:

Indexen

Idealiter heb je deze indexen met meerdere kolommen (met kolommen in deze volgorde):

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

Als de tafels voldoende zijn gestofzuigd, krijgt u drie scans met alleen index en wordt de hele operatie een fluitje van een cent.

Verkrijg pre-INSERT waarden?

Als je dat echt wilt (wat volgens mij niet het geval is), overweeg dan:



  1. Hoe automatische mysql db-back-up te doen met mysql workbench

  2. MySQL SELECT n records baseren op GROUP BY

  3. verkeerde telling in query

  4. 2 manieren om een ​​database op een gekoppelde server te maken met behulp van T-SQL