Kod

Obecnie mój kod wygląda tak.

            $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>                    }
            }

Co chcę robić

Chcę uzyskać u.fname+u.mname+u.lname (Gdzie msghistory.from_id=users.id) jako $msg['from_name'], ponownie u.fname+u.mname+u.lname (ALE tym razem, gdzie msghistory.to_id=users.id) jako $ msg['to_name'].

Przykład

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

Jak widać, oznacza to, że użytkownik 1 wyśle ​​do użytkownika 5 wiadomość hi.

Powiedzmy, że w tabeli użytkowników fname, lname dla identyfikatora użytkownika = 1 - John Doe i dla 5 - George Smith Chcę pokazać to jako wynik wyjściowy

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

Pytanie

Wiem, że jest to możliwe przy co najmniej 3 zapytaniach. Ale próbuję znaleźć optymalny sposób. Czy jest to możliwe przy jednym i jedynym zapytaniu?

Aktualizacja

Na podstawie 2 przydatnych odpowiedzi użytkowników zmodyfikowałem zapytanie w to

            $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");
0
Tural Ali 14 luty 2012, 02:37

2 odpowiedzi

Najlepsza odpowiedź

Używanie jawnych sprzężeń i wyraźnych, czytelnych aliasów sprawia, że ​​jest to zarówno bardziej niezawodne zapytanie, jak i łatwiejsze do odczytania. Wypróbuj następujące rozwiązania:

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

Możesz zastąpić wybrane * tylko polami, które chcesz zwiększyć wydajność

1
user1207727 14 luty 2012, 02:53
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

Nie jestem pewien, czy potrzebujesz „grupuj według”

1
Nir Alfasi 14 luty 2012, 03:09