查找数据库中缺少的数据

时间:2010-09-30 20:27:05

标签: mysql null referential-integrity

我需要弄清楚一些聪明的MySQL代码片段,它允许我轻松地看到两个表,表中的ID如果存在则为NULL或者如果它们不存在则为空。

我有一个用户表和一个遗留表,在手动比较之外我无法弄清楚如何让它们一起出现在一个表中,所以我可以比较。我希望看到的是这样的:

+----------------------------+
| user_id | email     | uid  |
| 14      | me@me.com | 26   |
| 16      | ug@ug.com | NULL |
+----------------------------+

我知道有一种方法可以包含NULL或空值,但我不确定它是什么。到目前为止,这是我的疯狂SQL查询,是的,我知道在子选择中进行子选择很可怕:

select uid from users where mail IN (
    select email from legacy_users where id NOT IN (
        select sourceid from migrate_map_users
    )
);

这里涉及三个表,legacy_users => migrate_map_users => users。中间只是一个m2m,加入了两个。 legacy_users和users都有一个电子邮件列。和他们自己的id版本。

谢谢大家!

3 个答案:

答案 0 :(得分:1)

...

select u.uid, u.mail, l.email, l.id
from users u
left outer join legacy_users
    on u.mail = l.email

- 让你前往的两个问题

select u.uid, u.mail, l.email, l.id
from users u
left outer join legacy_users
    on u.mail = l.email
Where l.id is null

select l.email, l.id, u.uid, u.mail
from legacy_users l
left outer join users u
    on l.email = u.mail
Where u.uid is null

答案 1 :(得分:1)

您需要了解join types,特别是左连接和外连接:

SELECT u.uid, u.mail, lu.id
FROM users u
LEFT OUTER JOIN legacy_users lu 
    ON u.email = lu.mail
WHERE lu.id NOT IN
   (
        SELECT sourceid 
        FROM migrate_map_users
    );

LEFT OUTER JOIN将确保返回LEFT表中的所有记录,无论是否有相应的记录。

答案 2 :(得分:1)

感谢Oded的回答,这就是我最终的结果:

SELECT * 
FROM (
  SELECT id, mail, uid 
  FROM users  
  LEFT OUTER JOIN 
    legacy_users lu ON users.mail = lu.email 
  UNION DISTINCT 
  SELECT id, email, uid 
  FROM users  
  RIGHT OUTER JOIN 
    legacy_users lu ON users.mail = lu.email
) j 
WHERE uid IS NULL 
OR id IS NULL;

这也让我可以在结果上做点什么。奖金。

请注意,它在左连接中使用邮件,在右连接中使用电子邮件。由于邮件在右外连接中不存在,我们必须使用legacy_users中的电子邮件列,反之亦然。