Encontrar dados que estão faltando no banco de dados
-
26-09-2019 - |
Pergunta
Preciso descobrir um trecho MySQL inteligente que me permitirá ver facilmente duas tabelas, os IDs na mesa se existirem ou nulos ou vazios, se não existirem.
Eu tenho uma tabela de usuários e uma tabela herdada e, fora da comparação manual, não consigo descobrir como fazê -los aparecer juntos em uma tabela para que eu possa comparar. O que eu adoraria ver é algo assim:
+----------------------------+
| user_id | email | uid |
| 14 | me@me.com | 26 |
| 16 | ug@ug.com | NULL |
+----------------------------+
Eu sei que há uma maneira de incluir valores nulos ou vazios, mas não tenho certeza do que é. Aqui está minha consulta SQL perturbada até agora, sim, eu sei que é horrível fazer subseletes dentro dos subseletes:
select uid from users where mail IN (
select email from legacy_users where id NOT IN (
select sourceid from migrate_map_users
)
);
Existem três tabelas envolvidas aqui, legacy_users => migrate_map_users => users
. O meio é apenas um M2M que se junta aos dois. Legacy_users e usuários têm uma coluna de email. e sua própria versão de um ID.
Obrigado a todos!
Solução
Você precisa aprender sobre Juntar tipos, em particular à esquerda e externa se junta:
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
);
A junção externa esquerda garantirá que todos os registros na tabela esquerda sejam devolvidos, se houver um correspondente no direito ou não.
Outras dicas
??
select u.uid, u.mail, l.email, l.id
from users u
left outer join legacy_users
on u.mail = l.email
- Duas perguntas para você ir
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
Graças à resposta de Oded, foi isso que acabei com:
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;
Isso também me permitiu fazer um lugar nos resultados. Bônus.
Observe que está usando o correio na junção e um email esquerdo na junção direita. Como o correio não existiria na junção externa certa, precisamos usar a coluna de email de Legacy_users e vice -versa.