Denna teknik förenar tabellen mot sig själv i en underfråga, men den matchar bara en rad (baserat på contact_id och e-postmatchning. Tricket är att underfrågan bara returnerar en av e-postadresserna med MIN, teoretiskt sett den första alfabetiskt (inte tillförlitligt, men du sa att det inte spelade någon roll).
Jag har testat detta med bra resultat.
UPDATE
email
JOIN (SELECT contact_id, MIN(email) as email
FROM email GROUP BY contact_id) as singles
USING(contact_id, email)
set is_primary=1;