2012-01-03 9 views
8

Tengo una tabla con 6 columnas:ver todos los datos de las filas duplicadas en el oráculo

  • id
  • name
  • type_id
  • code
  • lat
  • long

Se requieren los tres primeros. ID es la clave privada, insertada automáticamente con una secuencia.

Tengo algunas filas que son duplicadas, tal como las definen TANTO el name como el type_id siendo iguales, pero me gustaría ver todos los datos de los incautos. No puedo encontrar los duplicados bastante simplemente:

SELECT name 
     , type_id 
FROM table1 
GROUP BY name 
     , type_id 
HAVING COUNT(*) > 1 

pero en realidad la visualización de toda la información que me está confundiendo. Sé que esto debería ser simple, pero estoy golpeando una pared aquí.

Respuesta

15

Siempre puede usar la consulta GROUP BY/HAVING en una cláusula IN. Esto funciona y es relativamente sencillo, pero puede no ser particularmente eficiente si el número de filas duplicadas es relativamente grande.

SELECT * 
    FROM table1 
WHERE (name, type_id) IN (SELECT name, type_id 
          FROM table1 
          GROUP BY name, type_id 
          HAVING COUNT(*) > 1) 

Es generalmente sería más eficaz utilizar las funciones analíticas con el fin de evitar golpear la mesa una segunda vez.

SELECT * 
    FROM (SELECT id, 
       name, 
       type_id, 
       code, 
       lat, 
       long, 
       count(*) over (partition by name, type_id) cnt 
      FROM table1) 
WHERE cnt > 1 

Dependiendo de lo que está planeando hacer con los datos y el número de duplicados de una fila en particular puede haber, también puede ser que desee unirse a table1 a sí mismo para obtener los datos en una sola fila

SELECT a.name, 
     a.type_id, 
     a.id, 
     b.id, 
     a.code, 
     b.code, 
     a.lat, 
     b.lat, 
     a.long, 
     b.long 
    FROM table1 a 
     JOIN table1 b ON (a.name = b.name AND 
         a.type_id = b.type_id AND 
         a.rowid > b.rowid) 
+0

Lo primero que pensé fue en la primera consulta, pero no sabía si podrías usar dos columnas en una cláusula IN. Creo que debería haberlo intentado. Gracias. – Marc

1
SELECT * 
FROM table1 t1 
WHERE (t1.name,t1.type_id) in (SELECT DISTINCT name 
               , type_id 
           FROM  table1 
           GROUP BY name, type_id 
           HAVING COUNT(*) > 1) 

Lo haría.

HTH

1

Puede hacer un auto se unen en la tabla para encontrar todos los pares de duplicados:

SELECT 
    a.name name 
, a.type_id type_id_a 
, a.code code_a 
, a.lat  lat_a 
, a.long long_a 
, b.code code_b 
, b.lat  lat_b 
, b.long long_b 
FROM table1 a 
JOIN table1 b 
ON a.name = b.name 
AND a.type_id = b.type_id 
AND a.ROWID > b.ROWID 

Para asegurarse de que una fila no coincide con sí mismo y cada par sólo se emite una vez, Agregué a.ROWID > b.ROWID, que funciona para Oracle. Necesitará una forma diferente de mantenerlos separados si utiliza una base de datos diferente.

+0

Presumiblemente, desea una condición de unión adicional para asegurarse de que la fila devuelta de 'A' y de' B' sean en realidad filas diferentes. Algo como 'AND a.id> b.id' o' AND a.rowid> b.rowid' –

+0

Gracias, he actualizado la respuesta. –

0

Aún no encuentra los dobles si uno de los campos comparados tiene un valor NULO. Para obtenerlos, utilizo nvl para relacionar valores NULL en los campos comparados con un valor que sé que no puede ocurrir en esa tabla/campo.

-2

Simplemente haga los NULLS 0 ...

... use la función NVL.

Cuestiones relacionadas