我有一个名为last_msg
的表,在其中存储了两个用户之间的私人聊天的最新消息,并且在发送新的from
和to
列时精神病。我使用此表来显示诸如Facebook之类的咨询清单。我还将这张表用于其他事情,所以我宁愿解决下面描述的问题。
由于ON users.user_id = last_msg.from
我只能从发送提示的人那里获取数据,所以这是我得到的最好的结果。这是我当前的sql:
SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` = `last_msg`.`from`
WHERE `last_msg`.`to` = :user_id_logged OR `last_msg`.`from` = :user_id_logged_2
在INNER JOIN users
上,我只想从聊天中与之交谈的其他用户那里获取数据,而last_msg
上的数据可以来自发送者和接收者,就像facebook会。
所以我尝试了:
SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` != :user_logged
WHERE (`last_msg`.`to` = :user_logged_2 OR `last_msg`.`from` = :user_logged_3)
但是它不起作用,它返回表users
中所有用户的列表。关于如何解决的任何建议?
答案 0 :(得分:1)
您可以尝试两次联接用户表,一次用于from用户,另一次用于to用户,如下所示,还请注意,您需要使用LEFT Join才能从用户与用户之间获取所有信息。
SELECT `last_msg`.`msg`, `last_msg`.`from`, `FromUser`.`username`, `FromUser`.`avatar`,`ToUser`.`username`,`ToUser`.`avatar`
FROM `last_msg`
LEFT JOIN `users` as `FromUser`
ON `FromUser`.`user_id` = `last_msg`.`from`
LEFT JOIN `users` as `ToUser`
ON `ToUser`.`user_id` = `last_msg`.`to`
WHERE `last_msg`.`to` = :user_id_logged OR `last_msg`.`from` = :user_id_logged_2";
更新代码
SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` =`last_msg`.`to`
WHERE `last_msg`.`from`= :user_logged
UNION
SELECT `last_msg`.`msg`, `last_msg`.`to`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` =`last_msg`.`from`
WHERE `last_msg`.`to`= :user_logged
答案 1 :(得分:1)
这是获取上次发送给您的消息的方法:
SELECT msg, `from` as other_user_id
FROM last_msg
WHERE `to` = :user_logged;
如果您还希望最近发送的邮件:
SELECT msg, `to` as other_user_id
FROM last_msg
WHERE `from` = :user_logged;
您说每次聊天只存储最后一条消息。我读这本书是因为对于用户A和B,表中将只有一行(发送给B的最后一条消息A或发送给A的最后一条消息B)。因此,您可以将两个查询结合起来,每次聊天仍只显示最后一条消息。
SELECT m.msg, u.user_id, u.username, u.avatar
FROM
(
SELECT msg, `from` as other_user_id
FROM last_msg
WHERE `to` = :user_logged
UNION ALL
SELECT msg, `to` as other_user_id
FROM last_msg
WHERE `from` = :user_logged
) m
JOIN users u ON u.user_id = m.other_user_id;
UNION ALL
的替代方法是联接和CASE WHEN
:
SELECT m.msg, u.user_id, u.username, u.avatar
FROM last_msg m
JOIN users u
ON u.user_id = CASE WHEN :user_logged = m.from THEN m.to ELSE m.from END as other_user_id
WHERE :user_logged IN (m.from, m.to)
此ON
子句也可以写为
ON (u.user_id = m.from AND :user_logged = m.to)
OR (u.user_id = m.to AND :user_logged = m.from)
或
ON u.user_id IN (m.from, m.to) AND u.user_id <> :user_logged;
顺便说一句。选择您喜欢的东西。
这是在查询中仅使用一次用户ID参数的一种方法:
SELECT m.msg, u.user_id, u.username, u.avatar
FROM (select :user_logged as user_id) myself
JOIN last_msg m ON myself.user_id IN (m.from, m.to)
JOIN users u ON u.user_id IN (m.from, m.to) AND u.user_id <> myself.user_id;