我有两张桌子:
$email = a@a
SELECT * FROM users WHERE email<>'$email' AND channel <> '( SELECT * FROM inscricoes WHERE email ='$email')' ORDER BY RAND();
如何获得此结果?
d@d | ddddd
答案 0 :(得分:3)
我会使用反连接模式
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
获取所有行(除了用户的行=&#39; a @ a&#39;)
与这些行一起,从inscricoes
获取任何匹配的行。
扭曲是WHERE
子句中的条件。
我们保证任何匹配的行都将具有i.channel
的非NULL值(因为NULL值不满足ON子句中的相等条件)。因此,如果我们在i.channel
中排除具有非NULL值的行,则会留下没有匹配的行。
使用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
答案 1 :(得分:2)
我不确定是谁教你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
频道