Encontre linhas que tenham o mesmo valor em uma coluna no MySQL


209

Em uma tabela [member], algumas linhas têm o mesmo valor para a emailcoluna.

login_id | email
---------|---------------------
john     | john123@hotmail.com
peter    | peter456@gmail.com
johnny   | john123@hotmail.com
...

Algumas pessoas usaram um login_id diferente, mas o mesmo endereço de e-mail, nenhuma restrição exclusiva foi definida nesta coluna. Agora eu preciso encontrar essas linhas e ver se elas devem ser removidas.

Qual instrução SQL devo usar para encontrar essas linhas? (MySQL 5)

Respostas:


341

Essa consulta fornece uma lista de endereços de email e quantas vezes eles são usados, primeiro com os endereços mais usados.

SELECT email,
       count(*) AS c
FROM TABLE
GROUP BY email
HAVING c > 1
ORDER BY c DESC

Se você deseja as linhas completas:

select * from table where email in (
    select email from table
    group by email having count(*) > 1
)

1
count(1)funciona igualmente bem e tem melhor desempenho. (Aprendi esse truque de Stack Overflow ;-)
jpaugh

3
@jpaugh, não pode querer usar count(1) stackoverflow.com/questions/2710621/...
Tempestade

criou o que foi recursão essencialmente infinito ou algo sobre mysql resultando em um banco de dados mortos devido a "muitas conexões": - /
huygir


13

Aqui está uma consulta para encontrar emailos que são usados ​​para mais de um login_id:

SELECT email
FROM table
GROUP BY email
HAVING count(*) > 1

Você precisará da segunda consulta (aninhada) para obter a lista de login_idpor email.


10

A primeira parte da resposta aceita não funciona para o MSSQL.
Isso funcionou para mim:

select email, COUNT(*) as C from table 
group by email having COUNT(*) >1 order by C desc

5

use isso se sua coluna de email contiver valores vazios

 select * from table where email in (
    select email from table group by email having count(*) > 1 and email != ''
    )

3

Sei que essa é uma pergunta muito antiga, mas é mais para alguém que possa ter o mesmo problema e acho que isso é mais preciso do que se queria.

SELECT * FROM member WHERE email = (Select email From member Where login_id = john123@hotmail.com) 

Isso retornará todos os registros que têm john123@hotmail.com como um valor login_id.


2

Obrigado pessoal :-) Eu usei o abaixo porque eu só me importava com essas duas colunas e não muito com o resto. Funcionou muito bem

  select email, login_id from table
    group by email, login_id
    having COUNT(email) > 1

2
No caso em questão, COUNT (e-mail) sempre seria 1, portanto, sua consulta não retornará nada.
jutky

Não, a consulta realmente me deu os dados que eu precisava, que é distintamente o email e login_name daqueles que têm o mesmo e-mail
Libertine

Se você agrupar por email e login_id, contará a quantidade de linhas para o mesmo email e login, e essas são distintas no seu exemplo, portanto a contagem será sempre 1. Aqui está o violino com sua consulta que retorna 0 linhas: sqlfiddle. com / #! 9 / 4bbcaf / 3
jutky

1

Obtenha o registro inteiro como desejar, usando a condição com a consulta de seleção interna.

SELECT *
FROM   member
WHERE  email IN (SELECT email
                 FROM   member
                 WHERE  login_id = abcd.user@hotmail.com) 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.