2010-09-30 116 views
0

我需要弄清楚一些巧妙的MySQL代码片段,这将允许我轻松查看两个表,即表中的ID(如果它们存在)或NULL(空)或空(如果它们不存在)。查找数据库中缺失的数据

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

+----------------------------+ 
| user_id | email  | uid | 
| 14  | [email protected] | 26 | 
| 16  | [email protected] | 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和用户都有一个电子邮件列。和他们自己的id版本。

谢谢大家!

回答

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表中的所有记录都将被返回,无论是否有相应的记录。

+0

啊,你是对的。我想我正在寻找的是一个完整的外部联接。您的链接提供了一个在MySQL – 2010-09-30 20:43:28

+0

中执行此操作的配方@Chuck Vose - FULL OUTER应提供_both_表中的所有记录,而不管另一个记录是否具有相应的记录。 – Oded 2010-09-30 20:45:11

+0

MySQL不支持FULL OUTER JOIN语法。 – 2010-09-30 20:46:15

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 
+0

对不起,延期,我试了这个 – 2010-09-30 20:36:01

+0

我的问题是我试图找到一方可能不存在的记录。所以我想要所有电子邮件的列表,但我认为你的加入不允许存在l.email或u.mail不存在的记录(因为该记录不存在) – 2010-09-30 20:37:17

+0

我认为两者的结果这些查询可以让你朝着正确的方向前进 – Sage 2010-09-30 20:43:20

1

由于俄德的答案,这是我结束了:

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中的电子邮件列,反之亦然。