简体   繁体   中英

JOIN on conditional field

I have a table of messages:

id
sender_id
recipient_id

I want to pull all the messages of user (id: 1 ) where he was either the sender or the recipient and JOIN the "other guy" he was talking to.

something like:

SELECT * FROM `message`
LEFT JOIN `user` AS u ON IF(sender_id != 1, sender_id = u.id, recipient_id = u.id)
WHERE sender_id=1 OR recipient_id=1

the reason I don't join both the sender and recipient is that I already have the user I'm searching on, so I think it's a waste to join him on every message - unless you tell me otherwise!

This query I got from another SO question, but I've read it's not efficient at all, so what will be a better query?

This would work:

SELECT *
FROM message
JOIN users ON (message.sender_id = 1 AND user.id = message.recipient_id)
           OR (message.recipient_id = 1 AND user.id = message.sender_id)

Note that there are various other ways of doing this in a more performant fashion. This is the most straightforward method that I can see.

You could try a union:

(
SELECT * FROM `message`
INNER JOIN `user` u ON u.id = recipient_id
WHERE sender_id = 1
) UNION (
SELECT * FROM `message` 
INNER JOIN `user` u ON u.id = sender_id 
WHERE recipient_id = 1
)

Your way could work but the join won't use an index. If you want a fast join you need something like joined_table_indexed_field = some_expression , for example:

SELECT * 
FROM `message` m
JOIN `user` AS u ON u.id = IF(m.sender_id = 1, m.recipient_id , m.sender_id)
WHERE m.sender_id=1 OR m.recipient_id=1

In this case @Grim's solution is better because it doesn't rely on mysql to perform an union index_merge for the where clause.

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