我有四张桌子:
聊天(用户对用户)
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; $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本身)这两个查询,向用户显示与用户和页面的对话。我怎么能这样做?
答案 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)