2011-11-16 41 views
69

por lo que quiero hacer algo como el código SQL a continuación:¿Cómo encuentro duplicados en varias columnas?

select s.id, s.name,s.city 
from stuff s 
group by s.name having count(where city and name are identical) > 1 

para producir el siguiente, (pero ignoran donde sólo nombre o único partido de la ciudad, que tiene que ser en ambas columnas):

id  name city 
904834 jim London 
904835 jim London 
90145 Fred Paris 
90132 Fred Paris 
90133 Fred Paris 

Respuesta

96

duplican id de pares name y city:

select s.id, t.* 
from [stuff] s 
join (
    select name, city, count(*) as qty 
    from [stuff] 
    group by name, city 
    having count(*) > 1 
) t on s.name = t.name and s.city = t.city 
+0

Tenga en cuenta que si '' 'name''' o' '' city''' contienen '' 'null''', entonces no se informará en la consulta externa, pero se combinará en la consulta interna. –

+0

Si los valores pueden contener '' 'null''', entonces (a menos que me falta algo) necesita cambiarlo a' '' CROSS JOIN''' (producto cartesiano completo) y luego agregar '' ' WHERE cláusula''' como: '' 'WHERE ((nombre de pila = t.nombre) O (nombre de pila es nulo y t.nombre es nulo)) AND ((s.city = t.city) O (s.city es nulo y t.city es nulo)) '' ' –

0

Tienes que unirte a las cosas y unir el nombre y la ciudad. Luego, agrupa por conteo.

select 
    s.id, s.name, s.city 
from stuff s join stuff p ON (
    s.name = p.city OR s.city = p.name 
) 
group by s.name having count(s.name) > 1 
+0

Falla en SQL Server: todas las columnas no agregadas deben estar en GROUP BY – gbn

7

Algo como esto hará el truco. No sé sobre el rendimiento, así que haz algunas pruebas.

select 
    id, name, city 
from 
    [stuff] s 
where 
1 < (select count(*) from [stuff] i where i.city = s.city and i.name = s.name) 
14
SELECT name, city, count(*) as qty 
FROM stuff 
GROUP BY name, city HAVING count(*)> 1 
0

Estudia registro duplicado para más de una columna, mejor auto manera se unen con la Tabla

select * 
from [stuff] s 
join (
    select name, city 
    from [stuff] 
    group by name, city 
    having count(*) > 1 
) t on s.name = t.name and s.city = t.city 
0

Dada una tabla de etapas con 70 columnas y solo 4 representando duplicados, este código devolverá las columnas ofensivas:

SELECT 
    COUNT(*) 
    ,LTRIM(RTRIM(S.TransactionDate)) 
    ,LTRIM(RTRIM(S.TransactionTime)) 
    ,LTRIM(RTRIM(S.TransactionTicketNumber)) 
    ,LTRIM(RTRIM(GrossCost)) 
FROM Staging.dbo.Stage S 
GROUP BY 
    LTRIM(RTRIM(S.TransactionDate)) 
    ,LTRIM(RTRIM(S.TransactionTime)) 
    ,LTRIM(RTRIM(S.TransactionTicketNumber)) 
    ,LTRIM(RTRIM(GrossCost)) 
HAVING COUNT(*) > 1 

.