2016-10-28 3 views
1

У меня есть запрос, который возвращает все события для данного пользователя. Но сначала он ищет пользователя в подзапросе данного мобильного номера пользователя.MySQL различает два случая в зависимости от подзапроса

SELECT e.user_id, e.id FROM events e 
WHERE e.user_id = (SELECT u.user_id FROM users u WHERE u.mobile = '88888888') 

Если нет пользователя с указанным номером мобильного телефона, то будут возвращены строки. Если пользователь существует, но нет событий, то также будут возвращены строки. Я хотел бы иметь возможность различать эти два случая. Любая идея, как я мог сделать это в один вопрос?

Вот мой подход:

(SELECT (SELECT u.user_id FROM users u WHERE u.mobile = '88888888'), NULL) 
UNION 
(SELECT e.user_id, e.id FROM events e 
WHERE e.user_id = (SELECT u.user_id FROM users u WHERE u.mobile = '88888888')) 

Таким образом, я знаю, что я всегда буду иметь по крайней мере одну строку, которая просто проверяет, если пользователь существует. Поэтому, если user_id в первой строке NULL означает, что нет пользователя, и если это не NULL, значит, пользователь существует. Но мне это не нравится, потому что подзапрос поиска пользователя повторяется дважды и значительно медленнее, чем только первый запрос. Любые идеи для более быстрого решения?

+0

Какой результат вы действительно хотите? Вы хотите, чтобы все события, все пользователи или оба? –

+0

Если пользователь для данного мобильного номера существует и имеет события, я хочу эти события. В противном случае я хочу иметь возможность различать случай, когда существует 0 событий или пользователь не существует. Пока я могу достичь этого из своего кода приложения, который будет запускать этот запрос и вернуть результат, я счастлив. Я привел один пример добавления одной дополнительной строки к результатам, которые позволяют это сделать. Но я открыт для любых других предложений. Я не слишком разбираюсь в sql, например, может возникнуть ошибка, если пользователь не существует. Или возвращать разные столбцы для этих двух случаев. – Domajno

+0

Среди других идей, которые я имел, было, например, использовать переменную для хранения результата подзапроса и не выполнять ее дважды. Однако я не знаю, как переменные, например. '@ usr' ведет себя с точки зрения параллелизма - будут ли эти операции еще атомарными? Может ли это вызвать конфликты, если другой запрос в этом db также определил переменную @usr? – Domajno

ответ

0

Если вы хотите один результирующий набор, который будет показывать все мероприятия и пользователей, независимо от того, событие сопоставляется с пользователем или наоборот, то вы можете попробовать симулированное полное внешнее соединение:

SELECT COALESCE(u.user_id, 'NA'), 
     COALESCE(e.id, 'NA') 
FROM events e 
LEFT JOIN users u ON e.user_id = u.user_id 
WHERE u.mobile = '88888888' 
UNION ALL 
SELECT COALESCE(u.user_id, 'NA'), 
     COALESCE(e.id, 'NA') 
FROM events e 
RIGHT JOIN users u ON e.user_id = u.user_id 
WHERE u.mobile = '88888888'