加入两个表以列出用户的所有会话

时间:2018-06-12 19:23:22

标签: php mysql sql join select

我有四张桌子:

聊天(用户对用户)

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是用户登录的ID; $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是用户记录的ID; $idsChatid_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 :(得分:2)

首先,您将消息合并到一个查询中:

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