SELECT u.*, e.emails FROM users u , LATERAL ( SELECT ARRAY ( SELECT email FROM email WHERE user_id = u.user_id ORDER BY (email <> u.email) -- sort primary email first ) AS emails ) e WHERE user_id = 1;
You could create a VIEW with this for ease of use.
LATERAL requires Postgres 9.3. use a correlated subquery in pg 9.2:
SELECT *, ARRAY ( SELECT email FROM email WHERE user_id = u.user_id ORDER BY (email <> u.email) -- sort primary email first ) AS emails FROM users u WHERE user_id = 1;
WITH upd AS ( UPDATE users u SET email = NULL FROM (SELECT user_id, email FROM users WHERE user_id = 123 FOR UPDATE) old WHERE old.user_id = u.user_id AND u.user_id = 1 RETURNING old.* ) , del AS ( DELETE FROM email USING upd WHERE email.email = upd.email ) INSERT INTO email_deleted (email, user_id) SELECT email, user_id FROM upd;
Quick test for all of the above: SQL Fiddle.