INNER JOIN的问题我没有得到想要的结果

时间:2019-04-11 03:21:35

标签: mysql sql inner-join

我有一个名为last_msg的表,在其中存储了两个用户之间的私人聊天的最新消息,并且在发送新的fromto列时精神病。我使用此表来显示诸如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中所有用户的列表。关于如何解决的任何建议?

2 个答案:

答案 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;