2012-01-12 18 views
7

Considere la siguiente tabla:SQL: La eliminación de registros duplicados - aunque diferentes tipos

TAB6 
     A   B C 
---------- ---------- - 
     1   2 A 
     2   1 A 
     2   3 C 
     3   4 D 

considero, los registros de {1,2, a} y {2, 1, A} como duplicado. Necesito seleccionar y producir el siguiente conjunto de registros:

  A   B C      A   B C 
---------- ---------- -    ---------- ---------- - 
     1   2 A   or   2   1 A 
     2   3 C      2   3 C 
     3   4 D      3   4 D 

He intentado las siguientes consultas. Pero fue en vano.

select t1.* 
from t6 t1 
, t6 t2 
where t1.a <> t2.b 
and t1.b <> t2.a 
and t1.rowid <> t2.rowid 
/

     A   B C 
---------- ---------- - 
     1   2 A 
     2   1 A 
     2   1 A 
     2   3 C 
     3   4 D 
     3   4 D 

6 rows selected. 

O incluso esto:

select * 
from t6 t1 
where exists (select * from t6 t2 where t1.a <> t2.b and t1.b <> t2.a) 
/
     A   B C 
---------- ---------- - 
     1   2 A 
     2   1 A 
     2   3 C 
     3   4 D 

Ambos no funcionó.

La base de datos sería Oracle 10g. Buscando una solución SQL pura. Toda ayuda es apreciada.

+0

¿Qué es exactamente estás tratando de lograr? Por favor amplía esto. – simchona

+0

Necesito un SQL para producir el conjunto de registros {1, 2, A}, {2, 3, C} y {3, 4, D}. Para mí, {1, 2, A} y {2, 1, A} son registros duplicados y el conjunto de resultados debe tener solo una tupla ({{{{1}, {2}}}} {{{{{{2}}} {A}}, pero no ambos) –

+0

Para que quede claro, con "eliminar" te refieres a * filtro del conjunto de resultados * en lugar de * eliminar *. – APC

Respuesta

6

Utilice las funciones MÁS GRANDES() y MENOS() para identificar los valores comunes en múltiples columnas. Luego use DISTINCT para sacar los duplicados.

select distinct least(a, b) as a 
     , greatest(a, b) as b 
     , c 
from t6 

Esto le proporciona el conjunto preciso de registros que ha solicitado. Pero las cosas se volverán más complicadas si necesita incluir otras columnas de T6.


"Pero me preguntaba si esto funcionará para campos VARCHAR2 también?"

Sí, pero usará los valores ASCII para determinar el orden, que no siempre es lo que se podría esperar (o desear).

"Además, mi tabla T6 podría tener decenas de miles de registros."

Eso realmente no es una gran cantidad de datos en términos de hoy. DISTINCT causará una clasificación, que debería poder caber en la memoria a menos que A y B sean columnas VARCHAR2 realmente largas, pero probablemente incluso así.

Si esto es una consulta que va a querer correr mucho, entonces se puede construir un índice basado en las funciones de satisfacerlo:

create index t6_fbi on t6(least(a, b) 
          , greatest(a, b) 
          , c) 
/

Pero sería en realidad sólo se moleste si tiene una verdadera problema de rendimiento con la consulta.

+0

Gracias @APC, no pude verificar esto ahora. Pero me preguntaba si esto también funcionaría para los campos VARCHAR2.Además, mi mesa T6 podría tener decenas de miles de registros ... Agradezco su respuesta, pero todavía Stackoverflow no me permite votar aún. :( –

0

Si el orden de las columnas A y B no tienen importancia y siempre contiene un número entero, ¿qué tal:

select distinct 
    least(a, b) as a, 
    greatest(a, b) as b, 
    c 
from 
    t6 
Cuestiones relacionadas