【问题标题】:Select a MYSQL result where tables one and two match and two and three do not match选择表一和表二匹配而表二和三不匹配的MYSQL结果
【发布时间】:2015-07-18 00:53:39
【问题描述】:

我有两个表格,其中包含旧格式和新格式的用户。我想将旧格式的用户匹配到一个单独的表中,然后排除所有也出现在新用户格式表中的用户。我的数据是这样的:

Table newUsers:
+----+-------+-------+----------+
| id | oldid | first | last     |
+----+-------+-------+----------+
|  1 |    10 | John  | Kennedy  |
|  2 |    66 | Mitch | Kupchak  |
+----+-------+-------+----------+

Table posts:
+----+---------+
| id | user_id |
+----+---------+
|  1 |      10 |
|  1 |      66 |
|  1 |      88 | 
|  2 |      88 | 
|  2 |      28 | 
|  3 |      10 | 
+----+---------+

Table oldUsers:
+----+----------+-------+----------+
| id | username | first | last     |
+----+----------+-------+----------+
| 10 |        A | John  | Kennedy  |
| 66 |        B | Mitch | Kupchak  |
| 88 |        C | Dale  | Earnhardt|
+----+----------+-------+----------+

Result wantend:
+----+----------+-------+----------+
| id | username | first | last     |
+----+----------+-------+----------+
| 88 |        C | Dale  | Earnhardt|
+----+----------+-------+----------+

我想通过指定来选择我的结果:posts.id = 1 和 posts.user_id = oldUsers.id 和 newUsers.oldid != oldUsers.id 以便我只收到 oldUser.id 等于 88 因为他不在newUsers 列表。

我尝试过各种 JOINS 和 SUBQUERIES。我不断得到所有结果,而不是结果减去 newUsers 表中的相应条目。

【问题讨论】:

    标签: mysql select join subquery


    【解决方案1】:

    这是一种方法

    select 
    o.* from oldUsers o 
    left join newUsers n on o.id = n.oldid 
    left join posts p on  n.oldid = p.user_id or o.id = p.user_id 
    where n.id is null and p.id= 1;
    

    为了获得更好的性能,添加以下索引

    alter table newUsers add index oldid_idx(oldid);
    alter table posts add index user_post_idx (id,user_id);
    

    【讨论】:

    • 这行得通,但花了 3.5 秒,在解释时它说它用第一个左连接创建了大量行。所以使用起来效率太低了。
    • 你需要索引到表中,我已经为表添加了你可能需要的索引。我假设 olduser 和 newuser 的 id 都是主键,所以不需要对它们应用额外的索引。
    • 添加了它们,它确实将其平均降低到 0.023。但我自己的代码执行速度仍然快 5.22 倍。
    • 记住你在 postolduser 之间进行隐式连接,所以是的,内连接比外连接好。我添加了外连接,以防某些表中的一些丢失数据将被拾取。但是,如果有足够的空间,使用内部联接总是更好。
    【解决方案2】:
    select * from oldusers where id in
    
    select * from
    
    (select id from oldusers where id in
     select distinct userid from posts where id=1) 
     where id not in (select oldid from newusers);
    

    【讨论】:

    • #1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 3 行的“select * from (select id from oldusers where id in select disti”附近使用正确的语法
    【解决方案3】:

    我最终自己找到了答案,然后来到这里寻找其他人尝试过。 Abhik 的代码确实有效,但使用效率太低。我最终使用我自己的代码和 IS NULL 玩,直到我找到更有效的东西。

    select o.* from posts p, oldUsers o 
    LEFT JOIN newUsers n ON o.id = n.oldid 
    WHERE p.user_id = o.id AND p.id = 1 AND n.id IS NULL
    

    在 0.0044 秒内执行。我可以在生产网站上使用的东西。

    从上一个答案中添加索引后,它现在可以在 0.001 秒内执行,因此肯定会使用我自己的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多