Ничего лучше, кроме как в лоб, не придумывается.
select users.* from users
inner join user_events cities on users.id = cities.user_id
inner join
(select max(e.id) id, user_id from user_events e where event_type='city' group by user_id)
cities_fresh on cities_fresh.id = cities.id
inner join user_data names on users.id = names.id
inner join
(select max(d.id) id, user_id from user_data d where data_name='last_name' group by user_id)
names_fresh on names_fresh.id = names.id
inner join user_data phones on user.id = phones.user_id
where phone like '%7%' and city = 'Moscow' and last_name like '%uti%'
В общем, я бы пересмотрел ваше решение не перестраивать базу. Ничего не потеряется, просто добавьте новые таблицы с актуальными данными и поставьте для них триггеры или что там.
А еще можете свой запрос выложить, если он проще. Я не придумал.