Присоединиться к условному полю


У меня есть таблица сообщений:

id
sender_id
recipient_id

Я хочу вытащить все сообщения пользователя (id:1) где он был либо отправителем , либо получателем и присоединялся к "другому парню", с которым он разговаривал.

Что-то вроде:

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

Причина, по которой я не присоединяюсь к отправителю и получателю , заключается в том, что у меня уже есть пользователь, которого я ищу, поэтому я думаю, что это пустая трата времени, чтобы присоединиться к нему на каждом сообщении - , Если вы не скажете мне иначе!

Этот запрос я получил от другого вопроса SO, но я читал, что он вообще не эффективен, так что же будет лучшим запросом?

3 3

3 ответа:

Ваш способ может работать, но соединение не будет использовать индекс. Если вы хотите быстро присоединиться, вам нужно что-то вроде joined_table_indexed_field = some_expression, например:

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

В этом случае решение @Grim лучше, потому что оно не полагается на mysql для выполнения union index_merge для предложения where.

Это будет работать:

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)
Обратите внимание, что существуют различные другие способы сделать это более эффективным способом. Это самый простой метод, который я могу видеть.

Можно попробовать объединение:

(
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
)