2010-09-10 23 views
7

Estoy intentando crear una consulta que devolverá todos los registros no duplicados (únicos) en una tabla. La consulta deberá usar múltiples campos para determinar si los registros están duplicados.Consulta SQL para registros no duplicados

Por ejemplo, si una tabla tiene los siguientes campos; PKID, ClientID, Name, AcctNo, OrderDate, Charge, me gustaría usar los campos AcctNo, OrderDate y Charge para buscar registros únicos.

Tabla

PKID-----ClientID-----Name-----AcctNo-----OrderDate-----Charge 
1  JX100  John  12345  9/9/2010  $100.00 
2  JX220  Mark  55567  9/9/2010  $23.00 
3  JX690  Matt  89899  9/9/2010  $218.00 
4  JX100  John  12345  9/9/2010  $100.00 

necesitaría El resultado de la consulta sea:

PKID-----ClientID-----Name-----AcctNo-----OrderDate-----Charge 
2  JX220  Mark  55567  9/9/2010  $23.00 
3  JX690  Matt  89899  9/9/2010  $218.00 

He intentado usar SELECT DISTINCT, pero eso no funciona, ya que mantiene uno de los duplicados registros en el resultado. También he intentado usar HAVING COUNT = 1, pero eso devuelve todos los registros.

Gracias por la ayuda.

Respuesta

8

HAVING COUNT(*) = 1 funcionará si solo incluye los campos en el GROUP BY que está utilizando para buscar los registros únicos. (Es decir, no PKID, pero se puede usar MAX o MIN para volver ya que sólo tendrá un registro por grupo en el conjunto de resultados.)

+0

OK, me encontré con la consulta de nuevo usando count = 1 y funcionó ! Por alguna razón, cuando lo ejecuté antes, devolvió todos los registros. Gracias por el empujón es la dirección correcta. – nth

+0

¡Genial, me alegra que lo hayas hecho funcionar! – heisenberg

4
SELECT MAX(PKID)  AS PKID , 
     MAX(ClientID) AS ClientID, 
     MAX(Name)  AS Name , 
     AcctNo     , 
     OrderDate    , 
     Charge 
FROM  T 
GROUP BY AcctNo , 
     OrderDate, 
     Charge 
HAVING COUNT(*) = 1 

o

SELECT PKID  , 
     ClientID , 
     Name  , 
     AcctNo , 
     OrderDate , 
     Charge 
FROM YourTable t1 
WHERE NOT EXISTS 
     (SELECT * 
     FROM YourTable t2 
     WHERE t1.PKID  <> t2.PKID 
     AND  t1.AcctNo = t2.AcctNo 
     AND  t1.OrderDate = t2.OrderDate 
     AND  t1.Charge = t2.Charge 
     ) 
2

Basta con añadir:

GROUP BY AcctNo, OrderDate, Charge 
HAVING COUNT(1) = 1 

los GROUP BY grupos todas las filas con el mismo NUMCUENTA, OrderDate y de carga juntos, entonces el HAVING COUNT(1) = 1 muestra solo las filas donde solo había 1 progenitor.

1

Gracias kekekela por el empujón en la dirección correcta.

Aquí está la consulta que produjo el resultado que quería:

SELECT AcctNo, OrderDate, Charge FROM Table1 GROUP BY AcctNo, OrderDate, Charge 
HAVING (COUNT(AcctNo) = 1) AND (COUNT(OrderDate) = 1) AND (COUNT(Charge) = 1); 

O más simplificado basado en el ejemplo de Gus:

SELECT AcctNo, OrderDate, Charge FROM Table1 GROUP BY AcctNo, OrderDate, Charge 
HAVING COUNT(1) = 1; 
0

Usted puede simplemente desechar la PKID para devolver todos los registros:

SELECT DISTINCT 
      ClientID 
     , Name 
     , AcctNo 
     , OrderDate 
     , Charge 
FROM  table; 

Nota: Esto es ligeramente diferente de lo que está preguntando.
Devuelve un conjunto único eliminando el campo que no es único.
Con su ejemplo, está solicitando que devuelva los no duplicados.

Solo pude ver su ejemplo siendo útil si está intentando
para limpiar una tabla extrayendo los registros "buenos".

0

Se podría determinar los registros no únicos en primer lugar, y luego probar para aquellos registros que no están en ese conjunto - como esto

select * from mytable where pkid not in 
(select t1.pkid 
from mytable t1 inner join mytable t2 
on t1.pkid <> t2.pkid 
and t1.acctno = t2.acctno 
and t1.orderdate = t2.orderdate 
and t1.charge = t2.charge) 

la última parte de la consulta interna le permite jugar con los criterios de "igualdad "- agregue el número requerido de columnas para probar. Por supuesto, esto se pone mucho más interesante que sin clave principal :) En tales casos, por lo general terminan creando una

Ketil

+0

¿No debería la consulta leer '>' o '<' en lugar de '<>'? Con '<>', el resultado contendrá * ninguno * de las filas duplicadas en lugar de una sola copia – crizzis

+0

No, el <> asegura que no se prueba un registro contra sí mismo, igual que la solución # 2 de Martin Smiths. A < or > solo buscaría duplicados en pkids con valores de pkid más altos o más bajos, no lo suficiente para garantizar la exclusividad de las columnas de datos especificadas. –

0
SELECT GMPS.gen.ProductDetail.PaperType, GMPS.gen.ProductDetail.Size FROM 
GMPS.gen.ProductDetail GROUP BY GMPS.gen.ProductDetail.PaperType, 
GMPS.gen.ProductDetail.Size 
HAVING COUNT(1) = 1; 
Cuestiones relacionadas