简体   繁体   English

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

[英]Problem with INNER JOIN I'm not getting the desired result

I have a table called last_msg , in there i store the last mensage from a private chat between two users, and i update the column from and to when I send a new mensage. 我有一个名为表last_msg ,在那里,我的最后一个mensage存储从两个用户之间的私人聊天,我更新列fromto时我送一个新的mensage。 I use this table to show a list of mensages like facebook. 我使用此表来显示诸如Facebook之类的咨询清单。 I also use this table to another things, so i would rather fix the problem described as bellow. 我还将这张表用于其他事情,所以我宁愿解决波纹管问题。

Because of the ON users.user_id = last_msg.from i get data only from who is sending the mensage, this was the best i got... This is my current sql: 由于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

On the INNER JOIN users I want to get data only from the other user that i'm talking to in the chat, and the data from last_msg can be from both sender and receiver, as the facebook does. INNER JOIN users我只想从我正在聊天中last_msg交谈的其他用户获取数据,而last_msg的数据可以来自发件人和收件人,就像facebook一样。

So i tried: 所以我试着:

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)

But it did not work, it's returning a list of all users in the table users . 但是它不起作用,它返回表users中所有用户的列表。 Any suggestions about how can i fix it? 关于如何解决的任何建议?

You can try joining the users table two times, one for the from user and the other for the to user like shown below, also note you need to use LEFT Join in order to get all from and to users. 您可以尝试两次联接用户表,一次用于发件人,另一次用于发件人,如下所示,还请注意,您需要使用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";

Updated Code 更新的代码

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 

This is how to get the messages last sent to you: 这是获取上次发送给您的消息的方法:

SELECT msg, `from` as other_user_id
FROM last_msg
WHERE `to` = :user_logged;

If you also want the messages you last sent: 如果您还希望最后发送的消息:

SELECT msg, `to` as other_user_id
FROM last_msg
WHERE `from` = :user_logged;

You say you store only the one last message per chat. 您说每次聊天只存储最后一条消息。 I read this as for users A and B there will only be one row in the table (either the last message A sent to B or the last message B sent to A). 我读这本书是因为对于用户A和B,表中将只有一行(发送给B的最后一条消息A或发送给A的最后一条消息B)。 So you can just combine the two queries and still show only one last message per chat. 因此,您可以将两个查询组合在一起,并且每次聊天仍只显示最后一条消息。

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;

An alternative to UNION ALL is a join and CASE WHEN : UNION ALL的替代方法是join和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)

This ON clause can also be written as 这个ON子句也可以写成

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

or 要么

ON u.user_id IN (m.from, m.to) AND u.user_id <> :user_logged;

by the way. 顺便说说。 Pick what you like better. 选择您喜欢的东西。

And here is a way to use the user ID parameter only once in the query: 这是在查询中仅使用一次用户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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM