ПРИМЕЧАНИЕ: Похоже, что мой ответ ниже не работает с SQLite 3.7.5, я предлагаю использовать запрос "JOIN", предложенный Ларри.
Вы близко. Вам нужно сначала отсортировать все записи, используя таблицу подзапросов, а затем сгруппировать их. Значения, которые возвращаются в наборе результатов, будут из последней строки в каждой группе. Таким образом, вы действительно хотите, чтобы новые сообщения появлялись внизу, если вы пытаетесь получить новое сообщение. «GROUP BY» уже гарантирует, что вы получите одну строку для каждого ContactId.
SELECT * FROM (SELECT * FROM messages ORDER BY MessageTime) GROUP BY ContactId
Предложение HAVING не требуется. Я не использовал его раньше, но в соответствии с документами, предложение HAVING отбрасывает целые группы, которые не совпадают, но не похоже, что вы хотите, чтобы какие-либо группы были отброшены, вам нужны результаты из каждого ContactId.
Также обратите внимание, что в "ORDER BY" или "GROUP BY" нет подчеркивания.