Запрос sql выборка сообщений

237
28 апреля 2017, 18:24

Есть таблица messageprivate со структурой:

 id | from_user | to_user | message | date | status |

в ней хранятся сообщения. Из структуры ясно, что from_user - это пользователь который написал сообщение, to_user - кому он это написал, message - собственно само сообщение, date - когда написал и status - прочитано оно или нет, по умолчанию это поле равно 0, а когда пользователь которому оно было написано его читает оно меняется на 1.

Необходимо написать sql запрос который выведет сообщения сгруппированные типа как в контакте когда заходим в раздел сообщения - т.е. видим перечень переписок с каждым пользователем, а именно по последнему сообщению от каждого пользователя и количество непрочитанных сообщений.

Изначально нам известен наш id - т.е. когда мы пишем кому-то то наш id попадает в поле from_user, а когда нам кто-то пишет то наш id попадает в поле to_user.

3 часа уже под хвост...

Спасибо!

Answer 1
select if(from_user=@user,to_user,from_user) recipient,
       max(date) last_date,
       substr(max(concat(date,message)),20) last_msg,
       sum(status=0) not_seen
  from messageprivate
 where from_user=@user or to_user=@user
 group by recipient

@user это наш пользователь для которого выборка

Тест на sqlfiddle.com

Answer 2

На данных не тестил, но алгоритм примерно такой:

  • берем все отправленные сообщения, составляем переписку с людьми, которым мы писали. Присоединяем последнее сообщение, чтобы показывалось, как в переписке в вк во вкладке "Мои сообщения"

  • делаем то же самое, только со входящими сообщениями от пользователей

  • объединяем все в одну таблицу и сортируем по времени (для удобства у меня название таблицы mp вместо messageprivate)

select *
from (
    select to_user,
        mp1.message,
        mp1.date,
        m1.count_sent_unread
    from
    /* в подзапросе отправленные сообщения от нас с макс датой и количеством непрочитанных */
          (select from_user, to_user,
              max(date) as max_sent_date,
              sum(if(status = 0, 1, 0)) as count_send_unread
           from mp
           where from_user = 100
           group by from_user, to_user
           ) m1
      join /* чтобы получить последнее сообщение в переписке */
          mp1 ON m1.from_user = mp1.from_user and m1.to_user = mp1.to_user and m1.max_sent_date = mp1.date
    UNION /* объединяем то же самое, только со входящими сообщениями */
    select from_user,
        mp2.message,
        mp2.date,
        m2.count_receive_unread
    from
    /* в подзапросе входящие сообщения с макс датой и количеством непрочитанных */
          (select from_user, to_user,
              max(date) as max_receive_date,
              sum(if(status = 0, 1, 0)) as count_send_unread
           from mp
           where to_user = 100
           group by from_user, to_user
           ) m2
      join mp2 ON m2.from_user = mp2.from_user and m2.to_user = mp2.to_user and m2.max_sent_date = mp2.date) mes
order by date desc
READ ALSO
удаление дублей из большой mysql базы

удаление дублей из большой mysql базы

Здравствуйте! есть табличка mysql с 60 млн записями, имеет поля: ID, keyword (varchar 200), catНеобходимо оставить только записи с уникальными значениями...

247
Не могу понять запись создания взаимных ссылок между классами

Не могу понять запись создания взаимных ссылок между классами

У меня есть два класса: Controller и ViewerОни вроде как связаны между собой

221
регулярное выражение для пути

регулярное выражение для пути

помогите с регулярным выражением, нужно чтобы к примеру путь C:\Users\Admin\ разделился на C:\Users\ и на Admin\ ,понял что нужны регулярные выражения, но не понял...

203
Вывод данных из БД при загрузке JSP - Java БД

Вывод данных из БД при загрузке JSP - Java БД

Доброго времени сутокЯ совсем новичок в Java

413