Первое что в голову приходит:
SELECT MAX(msg-id) AS msg-id, user_id, msg-text FROM (
SELECT msg-id, msg-for AS user_id, msg-text
FROM messages
UNION
SELECT msg-id, msg-from AS user_id, msg-text
FROM messages
) AS t
GROUP BY user_id
ORDER BY user_id
Да, эмуляция СТЕ не прошла безболезнено. :)
Вот так попробуй, под мускул можно сделать запись и покороче, но в таком виде будет универсальней:
SELECT a.msg_id, c.user_id, a.msg_text
FROM messages AS a
JOIN
(
SELECT max(max) AS msg_id, user_id FROM (
(SELECT msg_from AS user_id, max(msg_id) from messages group by msg_from)
UNION
(SELECT msg_for AS user_id, max(msg_id) from messages group by msg_for)
) as b GROUP BY user_id
) c ON a.msg_id = c.msg_id
ORDER BY c.user_id;