简体   繁体   中英

Selecting multiple values from two table at once

Code

Currently my code looks like that.

            $stmt = $this->db->prepare("SELECT m.id, m.from_id, m.to_id, m.subject, m.date, m.deleted, m.read, u.fname, u.mname, u.lname FROM msghistory AS m,users AS u WHERE m.from_id=u.id AND m.to_id=u.id AND GROUP BY m.id DESC");
            $stmt->execute();
            $stmt->store_result();
            if ($stmt->affected_rows > 0) {
                $msg = array();
                $stmt->bind_result($msg['id'], $msg['from_name'], $msg['to_name'], $msg['subject'], $msg['message'], $msg['date'], $msg['deleted'], $msg['read']);

                while ($stmt->fetch()) {
                    <echoing results one by one>                    }
            }

What I want to do

I want to get u.fname+u.mname+u.lname (Where msghistory.from_id=users.id ) as $msg['from_name'] , again u.fname+u.mname+u.lname ( BUT this time where msghistory.to_id=users.id ) as $msg['to_name'].

Example

message | from_id | to-id
hi      | 1       | 5

As you see, this means, user 1 send to user 5 message hi.

Lets say in users table fname, lname for user id=1 - John Doe and for 5 - George Smith I want to show this as output result

message | from_id | to-id
hi      | John Doe| George Smith

Question

I know that it's possible with at least 3 queries. But trying to find optimal way. So,is that possible with one and only query?

Update

Based on 2 usefull answers by users I modified query into this

            $stmt = $this->db->prepare("SELECT 
                message.id, message.from_id, message.to_id, message.subject, 
                message.date, message.deleted, message.read, 
                CONCAT_WS(' ',sender.fname, sender.mname, sender.lname) AS sender_name, 
                CONCAT_WS(' ',recipient.fname, recipient.mname, recipient.lname) AS recipient_name,  
                FROM msghistory AS message 
                LEFT JOIN users AS sender ON sender.id=message.from_id, 
                LEFT JOIN users AS recipient ON recipient.id=message.to_id 
                GROUP BY message.id DESC");
SELECT m.id, m.from_id, m.to_id, m.subject, m.date, 
m.deleted, m.read, u1.fname, u1.mname, u1.lname, 
u2.fname, u2.mname, u2.lname,       
FROM msghistory AS m,users AS u1, users As u2     
WHERE m.from_id=u1.id AND m.to_id=u2.id 
GROUP BY m.id DESC

I'm not sure you need the "group by"

Using explicit joins and clear, readable aliases makes it both a more robust query and easier to read. Try the following:

SELECT message.*, recipient.*, sender.*
FROM msghistory AS message
INNER JOIN users AS recipient ON recipient.id=m.to_id
INNER JOIN users AS sender ON sender.id=m.from_id

You can replace the select *s with just the fields you want for efficiency

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