Reputation: 1089
I have 4 tables
I'm trying to get friend requests and new messages in a single query. It works well but as I left join 'friendsreuqests' I get multiple rows.
Here is my query:
SELECT username,
f1.userid as reqId,
m1.msg, m1.userid,
p1.picHash, p1.extension, UNIX_TIMESTAMP( m1.sent ) AS date
FROM users
LEFT JOIN pictures p1 ON p1.userid = users.id
LEFT JOIN messages m1 ON m1.contactid = users.id AND m1.delivered =0
LEFT JOIN friendrequests f1 ON f1.contactid = users.id AND f1.delivered=0 AND f1.request =1
WHERE users.id =7
ORDER BY date ASC
This is the MySQL result:
Kungen 3 gregegerg 1 dc825b1c8a35593be4d172db7 jpg 1369839537
Kungen 12 gregegerg 1 dc825b1c8a35593be4d172db7 jpg 1369839537
Kungen 3 HEJH 1 dc825b1c8a35593be4d172db7 jpg 1369839540
Kungen 12 HEJH 1 dc825b1c8a35593be4d172db7 jpg 1369839540
As you see there result is doubled. I want to get only two rows at this point. If I have two new messages but no new friends requests those 2 rows should be NULL.
Upvotes: 0
Views: 170
Reputation: 468
The problem is that after the first two joins you get this if im right:
Kungen gregegerg 1 dc825b1c8a35593be4d172db7 jpg 1369839537
Kungen HEJH 1 dc825b1c8a35593be4d172db7 jpg 1369839540
now with joining the friendrequests table on f1.contactid = users.id
you join the requests for user 3 and 12 on both entries with the userid 1
resulting in:
Kungen 3 gregegerg 1 dc825b1c8a35593be4d172db7 jpg 1369839537
Kungen 12 gregegerg 1 dc825b1c8a35593be4d172db7 jpg 1369839537
Kungen 3 HEJH 1 dc825b1c8a35593be4d172db7 jpg 1369839540
Kungen 12 HEJH 1 dc825b1c8a35593be4d172db7 jpg 1369839540
Now to get the right result you would need to join the friendrequests table on something that connects with the message or timestamp as this is the only column that differs.
Upvotes: 0
Reputation: 1269693
If you want to get friend requests and messages in a single query, then I would expect the query to have a union all
. Your query is doing a join between the tables. This would add information about friend requests as additional columns. You want it in additional rows.
I'm not sure which fields in the friends table correspond to which fields that you are requesting. But here is an example of a query using union all
:
SELECT username, users.id as reqId, m1.msg, m1.userid,
p1.picHash, p1.extension, UNIX_TIMESTAMP( m1.sent ) AS date
FROM users LEFT JOIN
pictures p1 ON p1.userid = users.id LEFT JOIN
messages m1 ON m1.contactid = users.id AND m1.delivered =0
WHERE users.id =7
union all
SELECT username, users.id as reqId, NULL, NULL,
NULL, NULL, UNIX_TIMESTAMP( f1.sent ) AS date
FROM users LEFT JOIN
friendrequests f1
ON f1.contactid = users.id AND f1.delivered=0 AND f1.request =1
ORDER BY date ASC
Upvotes: 2
Reputation: 33273
If you LEFT JOIN
both friend requests and messages like you do you will get No of messages times number of friend requests in your result set. In you example you have 2 requests and 2 messages resulting in (2*2=) 4 rows.
Perhaps you should consider using a union
instead? With a union
you will be able to get one row for each friend request and one row for each message. That should suit your needs better.
You will still get 4 rows in your example (2+2), though.
Upvotes: 1
Reputation: 4511
Adding GROUP BY
clause with all fields in it will surely help, but you will have to decide, which value for second field you want to keep (3 or 12).
If you definitely know, that there are always 2 rows with that field differing, than you can select both MIN(m1.msg)
and MAX(m1.msg)
Upvotes: 0