У меня две таблицы:
$email = a@a
SELECT * FROM users WHERE email<>'$email' AND channel <> '( SELECT * FROM inscricoes WHERE email ='$email')' ORDER BY RAND();
Как получить этот результат?
d@d | ddddd
Я бы использовал шаблон против объединения
SELECT u.email
, u.channel
FROM users u
-- anti-join, exclude rows with matching channel
LEFT
JOIN inscricoes i
ON i.email = 'a@a'
AND i.channel = u.channel
WHERE i.email IS NULL
AND u.email <> 'a@a'
ORDER BY u.channel
Это говорит о том, чтобы получить все строки от users
(кроме строки для пользователя = 'a @a')
И вместе с этими строками, получите любые соответствующие строки от inscricoes
.
Твист - это условие в WHERE
.
Мы гарантируем, что любые строки, имеющие совпадение, будут иметь значение, i.channel
NULL для i.channel
(поскольку значение NULL не удовлетворяет условию равенства в предложении ON). Поэтому, если мы исключаем строки, которые имеют значение, i.channel
NULL, в i.channel
, мы оставляем строки, которые не имеют соответствия.
Эквивалентный результат может быть получен с использованием шаблона NOT EXISTS (correlated subquery)
SELECT u.email
, u.channel
FROM users u
WHERE u.email <> 'a@a'
AND NOT EXISTS
( SELECT 1
FROM inscricoes i
WHERE i.email = 'a@a'
AND i.channel = u.channel
)
ORDER BY u.channel
Я не уверен, кто научил вас ORDER BY RAND()
трюк, но я настоятельно советую забыть его навсегда. Если вам абсолютно не нужны результаты в случайном порядке, это просто замедляет ваши запросы без причины.
Тем не менее, учитывая предоставленные вами данные, вы можете сделать что-то вроде этого:
SELECT
users.email as email,
users.channel as channel
FROM
users
LEFT JOIN
inscricoes ON users.channel = inscricoes.channel
WHERE
users.email <> '$email'
AND
inscricoes.email <> '$email'
Это создаст временную таблицу:
+-------------+---------------+------------------+--------------------+
| users.email | users.channel | inscricoes.email | inscricoes.channel |
+-------------+---------------+------------------+--------------------+
| a@a | aaaaa | NULL | NULL |
| b@b | bbbbb | a@a | bbbbb |
| c@c | ccccc | a@a | ccccc |
| d@d | ddddd | NULL | NULL |
+-------------+---------------+------------------+--------------------+
Затем он запускает запрос на эту временную таблицу. Однако, если у вас есть несколько значений в таблице inscricoes
для одного канала, это может привести к дублированию результатов. Если это случай, сообщите нам, и я буду работать над лучшим запросом для вас.
Основываясь на вашем комментарии, я думаю, что у меня есть лучшее представление о том, чего вы пытаетесь достичь. Попробуйте этот запрос:
SELECT
distinct(channel)
FROM
users
WHERE
email <> '$email'
AND
channel NOT IN (
SELECT channel FROM inscricoes WHERE email = '$email'
)
Это будет:
a@a
(подзапрос)a@a
d@d
а неc@c
?SELECT * FROM users WHERE email<>'$email' AND channel not in (SELECT channel FROM inscricoes WHERE email ='$email') ORDER BY RAND();
?