Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Resultado de consulta evitando duplicados de ciertos registros

Hola a todos, después de buscar un rato (quizás no he sabido buscar bien) no he encontrado ningún hilo que me saque de la duda.
Resulta que en una tabla de registros hay un campo que almacena una referencia y esta se puede repetir en varios registros.
Necesito una consulta que me devuelva sólo un registro (con todos sus campos) de cada valor diferente del campo referencia; intuyo que se utiliza el atributo distinct pero he hecho pruebas y no acierto.

También me vale una solución que teniendo en un ClientDataSet todos los datos, pueda realizar un filtrado y me quede con los registros que cumplan la condición mencionada antes, que muestre un registro por cada valor del campo referencia.

Gracias de antemano por vuestro tiempo y ayuda.

Sergio
Responder Con Cita
  #2  
Antiguo 05-06-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por Sergio J. Ver Mensaje
intuyo que se utiliza el atributo distinct pero he hecho pruebas y no acierto.
Pues pon el código que lo veamos.
Y explica qué quiere decir con "no acierto", ¿en qué no aciertas?
Responder Con Cita
  #3  
Antiguo 06-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Bien, en la tabla lo que tengo es esto:

Código:
id.     referencia   campo1   campo2...
1         0101          23       12
2         0101          54       32
3         0101          43       43
4         0102          12       54
5         0103          32       45
...

Dados estos datos, me interesa una consulta tal que al aplicarla, me quede con los registros en los que no se repita el campo referencia, como en este caso:


Código:
id.     referencia   campo1   campo2...
1         0101          23       12
4         0102          12       54
5         0103          32       45
...

He probado algo así como:

Código SQL [-]
select (dintinct referencia), t.*
from tabla t
where condiciones

pero no ha funcionado.

O también me interesa que a la hora de filtrar los datos en la aplicación, en el evento OnFilterRecord, haga lo mismo pero no encuentro la forma.

A ver si alguien me echa una mano, gracias.

Sergio
Responder Con Cita
  #4  
Antiguo 06-06-2014
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Puedes provar algo del tipo:

select * from tabla t1 where ((select count(*) from tabla t2 where t1.referenca=t2.referencia)<2 )
Responder Con Cita
  #5  
Antiguo 06-06-2014
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.457
Poder: 20
newtron Va camino a la fama
Hola.

Yo no soy experto en sql pero prueba a añadir a tu instrucción la cláusula "GROUP BY REFERENCIA"

Saludos
__________________
Be water my friend.
Responder Con Cita
  #6  
Antiguo 06-06-2014
Avatar de duilioisola
[duilioisola] duilioisola is online now
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.731
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Creo que esta es la consulta que quieres:

Código SQL [-]
/*
Traigo todos los registros de tabla
donde el id corresponda a la primera ocurrencia de cada referencia
*/
select *
from tabla
where
id in (select min(id)
       from tabla
       group by referencia)
Responder Con Cita
  #7  
Antiguo 06-06-2014
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.021
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por engranaje Ver Mensaje
Puedes provar algo del tipo:
select * from tabla t1 where ((select count(*) from tabla t2 where t1.referenca=t2.referencia)<2 )
Recuerda poner los tags al código fuente, ejemplo:



Gracias


Cita:
Empezado por newtron Ver Mensaje
Hola.
Yo no soy experto en sql pero prueba a añadir a tu instrucción la cláusula "GROUP BY REFERENCIA"
Saludos
Exacto.

El "problema" es que aunque se ponga distinct, al añadir el asterisco para el resto de campos, finalmente se trae todos, por eso hay que agrupar por ese campo "referencia".
En este caso no hace falta hacer un distinct, solamente es necesario agrupar:
Código SQL [-]
select * from tabla group by referencia
Responder Con Cita
  #8  
Antiguo 06-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Cita:
Empezado por engranaje Ver Mensaje
Puedes provar algo del tipo:

select * from tabla t1 where ((select count(*) from tabla t2 where t1.referenca=t2.referencia)<2 )
Gracias engranaje pero de esta manera no devuelve los registros que tienen más de un registro con la misma referencia.
Me devolvería esto:

Código:
id.     referencia   campo1   campo2...
4         0102          12       54
5         0103          32       45
...
...y creo que newtron tampoco ha acertado ya que al introducir un group by, en la sentencia select me obliga a poner todos los campos de la tabla y aún así tampoco resultaría...

Código:
select distinct a.referencia, count(a.referencia)
from tabla a
group by referencia
...esto funciona pero quiero que muestre todos los demás campos de la tabla.
Sin embargo si añado a la sentencia select todos los demás campos no funciona:

Código:
select distinct a.referencia, count(a.referencia), a.*
from tabla a
group by referencia
A esto me refería con lo de que "no acierto".
Responder Con Cita
  #9  
Antiguo 06-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Creo que esta es la consulta que quieres:

Código SQL [-]
/*
Traigo todos los registros de tabla
donde el id corresponda a la primera ocurrencia de cada referencia
*/
select *
from tabla
where
id in (select min(id)
       from tabla
       group by referencia)
Efectivamente, esta sería la consulta efectiva, ya que el resultado es el esperado pero se ralentiza un poco.
Por otro lado quería aclarar a casimiro que la consulta

Código SQL [-]
select * from tabla group by referencia

pide a gritos un campo por el cual agrupar y daría error.

Si no encuentro otra consulta sin anidaciones, cosa que creo sería imposible, pues me quedo con la de duilioisola que es la que me soluciona el problema.

Gracias a todos por vuestro tiempo y aportaciones.

Sergio J.
Responder Con Cita
  #10  
Antiguo 06-06-2014
aposi aposi is offline
Miembro
 
Registrado: dic 2006
Posts: 146
Poder: 18
aposi Va por buen camino
Cita:
Empezado por engranaje Ver Mensaje
Puedes provar algo del tipo:

select * from tabla t1 where ((select count(*) from tabla t2 where t1.referenca=t2.referencia)<2 )
Con esta solo devolveria los que no estan repetidos

prueba esto

Código SQL [-]
select * from tabla t1 where id = (select min(id) from tabla t2  where t1.referenca=t2.referencia )

Con esta consulta tendria que retornar lo que quieres
Responder Con Cita
  #11  
Antiguo 06-06-2014
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 13
engranaje Va por buen camino
Primero disculparme por no haber leido bien la pregunta y no darme cuenta de que necesitabas también una ocurrencia para cada registro repetido. Segundo seguir discupandome, esta vez por la omisión del tag sql y por haber escrito prueva en lugar de prueba, cuando quise editar para corregir ya no era posible.

Ahora la aportación que igual te sirve. Puede que con esta consulta obtengas lo que necesites con la velocidad que te gustaría:
Código SQL [-]
  SELECT t1.*
  FROM tabla AS t1
  LEFT OUTER JOIN tabla AS t2
 ON t1.referencia = t2.referencia  
 AND t1.id < t2.id
 WHERE t2.referencia IS NULL
Responder Con Cita
  #12  
Antiguo 09-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Gracias de nuevo a todos, con todas estas últimas consultas, ya sólo me queda elegir la más eficiente porque funcionan todas.

Un saludo

Sergio
Responder Con Cita
  #13  
Antiguo 11-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Tema solucionado
Responder Con Cita
  #14  
Antiguo 11-06-2014
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.457
Poder: 20
newtron Va camino a la fama
Cita:
Empezado por Sergio J. Ver Mensaje
Tema solucionado
¿Y nos vas a dejar con la intriga de qué has hecho al final?
__________________
Be water my friend.
Responder Con Cita
  #15  
Antiguo 11-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Bueno, la consulta que ha prevalecido a las demás es la siguiente de aposi:

Código SQL [-]
select * from tabla t1 where id = (select min(id) from tabla t2  where t1.referenca=t2.referencia )

...a pesar de ser anidada, se ejecuta rápido y el resultado es exactamente el esperado.

Gracias a todos, de verdad.

Sergio J.
Responder Con Cita
  #16  
Antiguo 11-06-2014
Avatar de duilioisola
[duilioisola] duilioisola is online now
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.731
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Una pequeña nota sobre la consulta:

Dependiendo de los índices (ascendente, descendente) probablemente la consulta mejore si pones max(id). Obviamente el registro será del último id y no del primero.
Si no te importe cuál de los registros salga, puedes probar con FIRST 1 id. Esto te seleccionará uno de los registros, pero no te asegura cual de todos. Se lo supone más óptimo porque en cuanto encuentra 1 deja de buscar. En los otros casos debe buscar en todos los que se cumplan la condición (t1.referencia=t2.referencia) y luego seleccionar uno.

Código SQL [-]
/* el primer registro de los que se repiten (ordenado por id) */
select * from tabla t1 where id = (select min(id) from tabla t2  where t1.referenca=t2.referencia)

/* el último registro de los que se repiten (ordenado por id) */
select * from tabla t1 where id = (select max(id) from tabla t2  where t1.referenca=t2.referencia)

/* uno de los registros de los que se repiten */
select * from tabla t1 where id = (select first 1 id from tabla t2  where t1.referenca=t2.referencia)
Responder Con Cita
  #17  
Antiguo 11-06-2014
Sergio J. Sergio J. is offline
Miembro
 
Registrado: may 2003
Ubicación: Andalucía (España)
Posts: 97
Poder: 21
Sergio J. Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Una pequeña nota sobre la consulta:

...
Código SQL [-]
...

/* uno de los registros de los que se repiten */
select * from tabla t1 where id = (select first 1 id from tabla t2  where t1.referenca=t2.referencia)
...
Efectivamente, va más rápido y no me importa cual de los registros con la misma referencia me devuelva. No sabía de la sentencia "first 1", no la había utilizado nunca.

Gracias
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Consulta SQL devuelve registros duplicados Malau SQL 5 26-05-2011 03:47:50
copiar ciertos registros de una tabla a otra JESUSNET Conexión con bases de datos 2 07-06-2008 17:53:13
Consulta de varios registros y como resultado varias columnas sierraja SQL 12 06-02-2008 13:04:22
Consulta para ver registros duplicados MarcoMae SQL 2 30-03-2005 19:40:43
Appnd Condicionado a ciertos registros JorgeBec Conexión con bases de datos 0 26-07-2004 22:56:42


La franja horaria es GMT +2. Ahora son las 11:29:49.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi