Объединить две таблицы, чтобы перечислить все разговоры пользователя - PullRequest
0 голосов
/ 12 июня 2018

У меня есть четыре таблицы:

чат (пользователи для пользователей)

id | id_user_from | id_user_to
1  | 1            | 2
2  | 1            | 3
3  | 3            | 2
4  | 4            | 1

сообщение (пользователи для пользователей)

id | content | date                | id_chat | id_user_from | id_user_to
1  | hi      | 2017-10-04 23:14:41 | 1       | 1            | 2
2  | hello   | 2017-10-04 23:15:03 | 1       | 2            | 1
3  | heey    | 2017-10-04 23:40:00 | 3       | 3            | 2
4  | ops     | 2018-01-04 20:00:00 | 4       | 4            | 1

page_chat (пользователи на страницах / страницах для пользователя)

id | id_user | id_page
1  | 1       | 1
2  | 1       | 3
3  | 4       | 3
4  | 4       | 2

page_message (пользователи на страницах / страницах для пользователя)

id | content | date                | id_page_chat | id_user | id_page | from (0 = user; 1 = page)
1  | from pg | 2017-07-04 23:14:41 | 1            | 1       | 1       | 1
2  | from usr| 2018-10-04 23:15:03 | 2            | 1       | 3       | 0
3  | to usr  | 2018-10-04 23:40:00 | 2            | 1       | 3       | 1
4  | hi page | 2018-10-04 23:40:00 | 3            | 4       | 3       | 0

И я использую следующий код для получения последнего сообщения каждого разговора:

(пользователи для пользователей) ($userId - идентификатор пользователя, зарегистрированного в системе;$idsChat - это id_chat, которые уже загружены - используется из-за бесконечной прокрутки):

select m1.*
from message m1
join
(
  SELECT MAX(id) as id
  FROM message
  WHERE $userId IN (id_user_from, id_user_to) AND id_chat NOT IN (".implode(",", $idsChat).")
  GROUP BY id_chat
  ORDER BY id DESC
) m2 on m1.id = m2.id

(пользователи на страницы / страницы для пользователя) ($userId - этоидентификатор пользователя; $idsChat - это уже загруженные id_page_chat (из-за бесконечной прокрутки):

select m1.*
from page_message m1
join
(
  SELECT MAX(id) as id
  FROM page_message
  WHERE id_user = $userId AND id_page_chat NOT IN (".implode(",", $idsChat).")
  GROUP BY id_page_chat
  ORDER BY id DESC
) m2 on m1.id = m2.id

И они отлично работают.Но теперь я хочу объединить (не знаю, с помощью PHP или самого SQL) эти два запроса, чтобы показать пользователю ваши разговоры с пользователями и страницами вместе.Как я могу это сделать?

1 Ответ

0 голосов
/ 12 июня 2018

Итак, сначала вы объединяете свои сообщения в один запрос:

select `content`, `date`, id as m_id, id_chat, id_user_from, id_user_to,
  null as p_id, null as id_page_chat, null as id_user, null as id_page, null as `from`
from message
union all
select `content`, `date`, null as m_id, null as id_chat, null as id_user_from, null as id_user_to,
  id as p_id, id_page_chat, id_user, id_page, `from`
from page_message

Затем вы можете использовать это в качестве базовой таблицы для своего запроса, чтобы искать самое последнее сообщение из каждого разговора.(Этот код был бы намного чище, если бы вы использовали приведенный выше запрос для создания представления и ссылались на него вместо этого.)

select *
from (select `content`, `date`, id as m_id, id_chat, id_user_from, id_user_to,
      null as p_id, null as id_page_chat, null as id_user, null as id_page, null as `from`
    from message
    union all
    select `content`, `date`, null as m_id, null as id_chat, null as id_user_from, null as id_user_to,
      id as p_id, id_page_chat, id_user, id_page, `from`
    from page_message) m1
join
(select max(m_id) as m_id, max(p_id) as p_id
   from (select `content`, `date`, id as m_id, id_chat, id_user_from, id_user_to,
          null as p_id, null as id_page_chat, null as id_user, null as id_page, null as `from`
        from message
        union all
        select `content`, `date`, null as m_id, null as id_chat, null as id_user_from, null as id_user_to,
          id as p_id, id_page_chat, id_user, id_page, `from`
        from page_message) all_msgs
   where $userId IN (id_user_from, id_user_to, id_user) 
     AND IFNULL(id_chat, id_page_chat) NOT IN (".implode(",", $idsChat).")
   group by id_chat, id_page_chat
   order by m_id desc, p_id desc
) m2 on (m1.m_id = m2.m_id or m1.p_id = m2.p_id)

sqlfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...