如何比较两个选择?

时间:2018-04-02 20:51:41

标签: php mysql sql

我有两张桌子:

enter image description here

  $email = a@a
  SELECT * FROM users WHERE email<>'$email' AND channel <> '( SELECT * FROM inscricoes WHERE email ='$email')' ORDER BY RAND();

如何获得此结果?

d@d    |    ddddd

2 个答案:

答案 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'
    )

这将:

  1. 获取a@a订阅的频道列表(子查询)
  2. 获取除a@a频道
  3. 之外的所有频道列表
  4. 过滤第二个列表中的第一个列表
  5. 返回所有结果(忽略重复)