2010-09-30 8 views
0

J'ai besoin de trouver un extrait MySQL intelligent qui me permettra de voir facilement deux tables, les identifiants de la table s'ils existent ou NULL ou vide s'ils n'existent pas.Recherche de données manquantes dans la base de données

J'ai une table d'utilisateurs et une table héritée et en dehors de la comparaison manuelle je ne peux pas figurer dehors comment les faire apparaître dans une table ainsi je peux comparer. Ce que j'aimerais voir quelque chose comme ceci:

+----------------------------+ 
| user_id | email  | uid | 
| 14  | [email protected] | 26 | 
| 16  | [email protected] | NULL | 
+----------------------------+ 

Je sais qu'il ya un moyen d'inclure des valeurs NULL ou vides, mais je ne suis pas sûr de ce qu'il est. Voici ma requête SQL dérangée jusqu'à présent, oui, je sais que c'est horrible à faire subselects intérieur du sous-requêtes:

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

Il y a trois tables impliquées ici, legacy_users => migrate_map_users => users. Le milieu est juste un m2m qui joint les deux. legacy_users et les utilisateurs ont tous les deux une colonne d'e-mail. et leur propre version d'un identifiant.

Merci à tous!

Répondre

1

Vous devez en apprendre davantage sur join types, en particulier à gauche et jointures externes:

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 
    ); 

La LEFT OUTER JOIN fera en sorte tous les enregistrements dans la table GAUCHE seront retournés, qu'il y en ait un correspondant dans le bon ou non.

+0

Ah, vous avez raison. Je pense que ce que je cherchais était un FULL OUTER JOIN. Votre lien fourni une recette pour faire exactement cela dans MySQL –

+0

@Chuck Vose - FULL OUTER devrait fournir tous les enregistrements de _both_ tables, si l'autre a un enregistrement correspondant ou non. – Oded

+0

MySQL ne supporte pas la syntaxe FULL OUTER JOIN. –

1

??

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

- deux requêtes pour vous aider à aller

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

Désolé pour le retard, j'essaie cela –

+0

Mon problème est que j'essaie de trouver les enregistrements où un côté peut ne pas exister. Donc je veux une liste de tous les emails, mais je pense que ta jointure ne permet pas les enregistrements où l.email ou u.mail n'existent pas (parce que cet enregistrement n'existe pas) –

+0

Je pense que les résultats des deux ces questions pourraient vous aider à aller dans la bonne direction – Sage

1

Merci à la réponse de Oded est ce que j'ai fini avec:

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; 

Cela m'a aussi permis de faire un où sur les résultats. Prime.

Notez qu'il utilise le courrier dans la jointure gauche et le courrier électronique dans la bonne jointure. Puisque le courrier n'existe pas dans la jointure externe droite, nous devons utiliser la colonne email de legacy_users et vice versa.

Questions connexes