简体   繁体   中英

Joining tables on two fields

I always have confusion when it comes into JOINING tables.

So, I have a table that stores the user details called tblUsers having the following fields(for the sake of simplicity, I am including only the required fields here while posting):

user_id
first_name

And I have another table which stores the messages called tblMessages :

msg_id
sender_id
recipient_id
msg_body

Now what am trying to do is to fetch all messages, with the user names too. What I have tried is this:

SELECT 
    `msg_id`, 
    (SELECT `first_name` FROM `tblUsers` WHERE `tblUsers`.`user_id` = `tblMessages`.`sender_id`) AS `sender_name`,
    (SELECT `first_name` FROM `tblUsers` WHERE `tblUsers`.`user_id` = `tblMessages`.`recipient_id`) AS `recipient_name`,
    `msg_body`
FROM `tblMessages`

It seems to be working at the moment. But is this the correct way for attaining my goal? Or will JOINing the tables will be better? The tblMessages can grow to a large number of rows probably. If we are going to do the JOIN, then we will do 2 LEFT JOINs? First, on the sender_id of tblMessages with user_id of tblUsers and again recipient_id of tblMessages with user_id of tblUsers . Is that correct?

Let me know your suggestions or corrections on my approach.

This is going to be your best query (It will run queries once, and then join tables on their indices):

SELECT m.`msg_id`, su.`first_name` AS `sender_name`, ru.`first_name` AS `recipient_name`, m.`msg_body`
FROM `tblMessages` m
LEFT JOIN `tblUsers` su ON m.`sender_id` = su.`user_id`
LEFT JOIN `tblUsers` ru ON m.`recipient_id` = ru.`user_id`;

When in doubt, use EXPLAIN right before your query to determine what indexes it's going to use, and how efficient it's going to be. Check out these sqlfiddles containing the EXPLAIN 's for each query.

You can read a bit about the reasoning for choosing this query over yours here and straight from the docs here . EXPLAIN is also a helpful tool that can help you understand where your bottlenecks are and what is causing performance issues on your database (This likely isn't going to impact it very much, but you can always do some performance tests when your database reaches a healthy size.

You should JOIN the same table twice, using two different aliases for example s and r:

SELECT
  m.msg_id,
  m.sender_id,
  s.first_name,
  m.recipient_id,
  r.first_name,
  m.msg_body
FROM
  tblMessages AS m
  LEFT JOIN tblUsers AS s ON m.sender_id=s.user_id
  LEFT JOIN tblUsers AS r ON m.recipient_id=r.user_id

but your approach is not wrong, it works and with proper indexes shouldn't be much slower.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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