Прежде чем вникать в проблему, сначала я объясню ситуацию. У меня есть две таблицы, такие как:
USERS TABLE
user_id
username
firstName
lastName
GROUPS TABLE
user_id
group_id
Я хочу получить всех пользователей, которые сначала называют LIKE '% foo%' и кто является частью группы с group_id = 'givengid'
Итак, запрос хотел бы что-то вроде этого:
SELECT user_id FROM users WHERE firstName LIKE '%foo'"
Я могу создать пользовательскую функцию sql, такую как ismember (user_id, group_id), которая вернет 1, если пользователь является частью группы, и 0, если они не являются, и это предложение WHERE в вышеупомянутом предложении select. Однако это означает, что для каждого пользователя, имя которого соответствует критериям, другой запрос должен быть запущен через тысячи других записей, чтобы найти потенциальное совпадение для записи в группе.
Таблица пользователей и групп будет содержать несколько сотен тысяч записей. Является ли более привычным использовать подход, определенный пользователем, или запускать запрос с помощью инструкции UNION? Если подход UNION лучше всего подходит, как выглядит запрос с инструкцией объединения?
Конечно, я буду тестировать тесты, но я просто хочу взглянуть на возможный диапазон решений для этой ситуации и наиболее эффективный/эффективный.
Вы должны использовать JOIN, чтобы пользователи соответствовали вашим двум критериям.
SELECT
user_id
FROM
users
INNER JOIN
groups
ON groups.user_id = users.users_id
AND groups.group_id = given_id
WHERE
firstName LIKE '%foo'
Вам не нужно использовать здесь UNION
или пользовательскую функцию; вместо этого вы можете использовать JOIN
(который позволяет присоединить одну таблицу к другой на основе набора эквивалентных столбцов):
SELECT u.user_id
FROM users AS u
JOIN groups AS g
ON g.user_id = u.user_id
WHERE g.group_id = 'givengid'
AND u.firstName LIKE '%foo'
Что делает этот запрос, так это объединение строк в таблице groups
в строки таблицы users
, когда user_id одинаково (так что если вы должны использовать SELECT *
, вы получите длинную строку, содержащую данные пользователя и данные группы для этого пользователя). Если для пользователя существует несколько строк groups
, несколько строк будут извлечены до того, как они будут отфильтрованы с помощью предложения WHERE
.
Используйте соединение:
SELECT DISTINCT user_id
FROM users
INNER JOIN groups ON groups.user_id = users.user_id
WHERE users.firstName LIKE '%foo'
AND groups.group_id = '23'
DISTINCT
гарантирует, что в результате не будет повторяться идентификатор пользователя.