Возможно, это тестовый пример чата. Первая реализация.
Что ты хотел показать в списке сообщений? Все сообщения, которые кто-то кому-то написал? Тогда он работает правильно. Счётчик только не используется и зачем то в таблице есть dialog_id, но ты его тоже не используешь, а вместо этого группируешь по from + to.
Я бы для удобства визуально чат по-другому построил.
Посмотри вот на такой мокап
https://icons8.com/2015/07/17/icons8-wpf-ui-framework/, точнее вот этот экран
take.ms/5F5rr
С левой стороны список контактов, кому недавно писал ты или кто ответил тебе.
Для его построения нужен такой запрос
SELECT DISTINCT A.`user_id`
FROM(
SELECT m1.`from` as `user_id`, m1.`date` FROM `messages` m1 WHERE m1.`to` = 7
UNION
SELECT m2.`to` as `user_id`, m2.`date` FROM `messages` m2 WHERE m2.`from` = 7
ORDER BY `date` DESC
) A
То есть список собеседников в порядке убывания даты последнего сообщения.
Если нужен счётчик сообщений, то посчитать по каждому собеседнику или диалогу.
Если нужен счётчик непрочитанных сообщений, то нужно по каждому собеседнику или диалогу хранить идентификатор последнего прочитанного сообщения и считать количество сообщений с идентификатором больше этого.
Может быть это и много запросов в базу, но я был сделал их разными под каждый нужный элемент.
Под список собеседников + счётчик сообщений - один запрос
Если нужен счётчик непрочитанных сообщений, то второй запрос или серия запросов, хотя можно попробовать и в первый уместить.
Под сообщения чата конкретного диалога - третий запрос.
Как тестовый пример - норм. Вопросов нет.
Если в пром эксплуатации, то хранить отдельные сообщения в реляционной базе накладно. Слишком много записей в таблицах. Желательно использовать NoSQL базу и хранить в одной записи базы один диалог целиком.