Mysql 内部联接有问题我没有得到期望的结果

Mysql 内部联接有问题我没有得到期望的结果,mysql,sql,inner-join,Mysql,Sql,Inner Join,我有一个名为last_msg的表,在那里我存储了两个用户之间私人聊天的最后一个尺寸,当我发送新的尺寸时,我更新了from和to列。我用这个表格来显示一系列的尺寸,比如facebook。我还使用这个表来处理其他事情,所以我宁愿修复下面描述的问题 因为ON users.user\u id=last\u msg.from我只从发送尺寸的人那里获得数据,这是我得到的最好的。。。这是我当前的sql: SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`

我有一个名为last_msg的表,在那里我存储了两个用户之间私人聊天的最后一个尺寸,当我发送新的尺寸时,我更新了from和to列。我用这个表格来显示一系列的尺寸,比如facebook。我还使用这个表来处理其他事情,所以我宁愿修复下面描述的问题

因为ON users.user\u id=last\u 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
在Internal JOIN用户上,我只想从聊天中与我交谈的另一个用户那里获取数据,来自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中所有用户的列表。有关于如何修复它的建议吗

您可以尝试两次加入users表,一次用于from用户,另一次用于to用户,如下所示,还请注意,您需要使用LEFT Join来获取所有from和to用户

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 

以下是如何获取上次发送给您的消息:

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,表中只有一行,要么是A发送给B的最后一条消息,要么是B发送给A的最后一条消息。因此,您可以将这两个查询合并在一起,并且每个聊天室仍然只显示最后一条消息

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;
在以下情况下,联合所有的一种替代方法是连接和案例:

本条款也可写成:

  ON (u.user_id = m.from AND :user_logged = m.to)
  OR (u.user_id = m.to AND :user_logged = m.from)

顺便说一下。选择你更喜欢的

下面是一种在查询中仅使用一次用户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;

MySQL有点生疏,但我认为您希望在用户表上进行选择,然后将其与最后一个消息表连接起来。您是否可以放置表数据的屏幕截图以及您期望的输出。另一方面,我会避免使用类似于的SQL关键字的名称。这迫使您总是向列中添加丑陋的反勾号。此外,这是从哪里来的?名字?身份证?更好的名称应该是to\u user\u id或sender\u user\u id或user\u id\u sender或类似名称,表明这是引用用户表中某行的用户id。如果我在用户上进行更改,此查询与我的第一个代码段工作相同。user\u id=last\u msg.from to ON users.user\u id=last\u msg.toHi能否将需要的内容汇总为输出,如果登录的用户与来自用户的用户相同,您想要什么?如果登录的用户不是来自用户,那么您想要什么?最好能给出一些示例数据和所需的输出作为示例。在facebook的左侧,你可以看到一个尺寸列表,显示的头像和用户名总是来自其他用户,但尺寸可以来自发送方和接收方。我把这些数据放在两个不同的表中,last_msg,在这个表中我存储msg,to,from,在表用户上我存储用户名和头像,在表用户上我只想获取不等于登录用户的头像和用户名。你明白了吗?如果我错了,请纠正我,那么你需要的是一个给定的userlogged用户,你想要与他聊天的所有其他用户?如果我错了,请纠正我,根据OP的场景,Union是对的?还是有必要包括所有工会成员?@Ajan Balakumaran:是的,工会也会在这里工作。但问题是,是否有必要包括所有工会成员?这是误导。UNIONALL是一个简单的命令,它只粘合两个数据集。UNION DISTINCT或简称UNION是更复杂的命令。它粘合两个数据集,并删除重复数据。因此,问题应该是:是否有必要在这里实行工会?答案是:不,不是。这就足够了,谢谢你的及时回复。我可以看到联合所有的开销很小,因为它没有删除重复项。kudos@Ajan巴拉库马兰:看来你误解了。工会都没有开销。工会有。假设我有两副扑克牌,一副只包含红心牌,另一副只包含数字牌,即没有杰克牌、皇后牌等。。现在,你要求我给你所有的牌,或者你要求我给你所有的牌,但在之前移除重复的牌,以便只获得一次每张牌,例如红心七号。这两项任务中哪一项对我来说更重要?@Ajan Balakumaran:啊,好吧,你的意思是减少开销。对不起,误解了:-
ON u.user_id IN (m.from, m.to) AND u.user_id <> :user_logged;
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;