SQL - Buscar dos registros en la misma tabla con varias columnas iguales

 
Vista:

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por Alfonso (1 intervención) el 26/01/2012 10:23:57
He buscado en el foro, aunque no hay nada que sea explicitamente similar, así que lanzo mi duda:

Tengo que encontrar, en LA MISMA TABLA, todos los registros que tengan exactamente UN ÚNICO duplicado, es decir, los registros que se repitan unicamente dos veces en la misma tabla... pero sólo para ciertas columnasEs decir, el duplicado tiene que cumplirse para varias columnas del registro, pero no todas (digamos 6 columnas por ejemplo).

Hay alguna forma eficiente de hacer esta consulta en SQL? La base de datos tiene varios millones de registros, y soluciones convencionales "brutas" hacen que la consulta pueda no terminar nunca... con lo cual cosas como COUNT(*) = 2 son muy peligrosas.

Gracias sabios!
Alfonso
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por leonardo_josue (1173 intervenciones) el 26/01/2012 16:39:18
Hola Alfonso...

lamentablemente para lo que quieres hacer, la opción de COUNT(") = 2 es la forma más eficiente de hacerlo, independientemente del número de registros que tengas en tu tabla... Sin embargo, las funciones de agrupación son de las sentencias más optimizadas, por lo que no creo que deba ser tardada, aquí lo que deberías mencionar es qué tan frecuente será el uso de esta consulta, si sólo se va a utilizar una vez pues no importaría que tardara algunos segundos o incluso minutos, pero si la consulta será de uso frecuente entonces si podrías tener problemas.

La consulta quedaría más o menos así.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
mysql> SELECT * FROM tabla;
+--------+--------+------------+
| campo1 | campo2 | campo3     |
+--------+--------+------------+
|      1 | uno    | 2012-01-01 |
|      2 | uno    | 2012-01-02 |
|      3 | dos    | 2012-01-01 |
|      4 | tres   | 2012-01-02 |
|      5 | uno    | 2012-01-03 |
|      6 | dos    | 2012-01-01 |
|      7 | tres   | 2012-01-01 |
|      8 | uno    | 2012-01-02 |
|      9 | dos    | 2012-01-01 |
+--------+--------+------------+
9 rows in set (0.64 sec)
 
mysql> SELECT campo2, campo3, COUNT(*) total
    -> FROM tabla GROUP BY campo2, campo3
    -> ORDER BY campo2, campo3;
+--------+------------+-------+
| campo2 | campo3     | total |
+--------+------------+-------+
| dos    | 2012-01-01 |     3 |
| tres   | 2012-01-01 |     1 |
| tres   | 2012-01-02 |     1 |
| uno    | 2012-01-01 |     1 |
| uno    | 2012-01-02 |     2 |
| uno    | 2012-01-03 |     1 |
+--------+------------+-------+
6 rows in set (0.00 sec)
 
mysql> SELECT campo2, campo3, COUNT(*) total
    -> FROM tabla GROUP BY campo2, campo3
    -> HAVING COUNT(*) = 2 ORDER BY campo2, campo3;
+--------+------------+-------+
| campo2 | campo3     | total |
+--------+------------+-------+
| uno    | 2012-01-02 |     2 |
+--------+------------+-------+
1 row in set (0.03 sec)


La opción con HAVING COUNT(*) = 2 es para regresar aquellos registros que se repiten exactamente dos veces.... en el SELECT deberías incluir todas las columnas que a considerar para obtener los duplicados y por supuesto incluirlas también en el GROUP BY (En el ejemplo la columna1 no interesa para detectar duplicados). Finalmente, recuerda manejar índices en tus tablas para que las consultas sean más rápidas.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de xve
Val: 135
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por xve (284 intervenciones) el 26/01/2012 19:00:44
Excelente Leo!!!

Creo que hay otra manera sin utilizar HAVING, lo que no se es hasta que punto es mejor, peor o es lo mismo... pero aquí te la expongo haber que te parece...
1
2
3
4
5
6
7
8
SELECT * FROM
='editor_indent'>(
SELECT campo2, campo3, COUNT(*) total
FROM tabla
GROUP BY campo2, campo3
) as s1
WHERE s1.total=2
ORDER BY s1.campo2, s1.campo3

Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por Viris (2 intervenciones) el 22/04/2014 19:01:53
XVE me ayudo muchisimo tu query, con el having no podia obtener lo que me pedia mi ejercicio....

(Encontrar los clientes que han hecho mas de 3 viajes...)

1
2
3
4
5
6
7
8
9
10
SELECT * FROM
(
SELECT P.nombre, P.apaterno, COUNT(*) total
FROM persona P, venta_boleto VB, cliente C
where P.id_persona = C.id_persona
and VB.id_cliente = C.id_cliente
GROUP BY P.nombre, P.apaterno
) as cli
WHERE cli.total > 3
ORDER BY cli.nombre, cli.apaterno;
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por Jose (1 intervención) el 18/06/2015 19:37:30
Buenas tardes, tengo un problema con mis tablas!

son 2 tablas precios y materiales.

debo insertar unos datos de la primera a la segunda pero me da un error de duplicar datos!

CREATE TABLE [TBL_PLAN_ESCO_PB_PRECIO_SOLP_SID] (
[CODIGOPROCESO] [char] (24) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[CODIGOMATERIAL] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[NUMEROSOLP] [varchar] (12) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[POSICION] [int] NOT NULL ,
[GCP] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[PRECIOVALORACION] [float] NULL ,
[MONEDA] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[CANTIDADSOLICITADA] [float] NULL ,
[MONTO] [float] NULL ,
[PORCENTAJEACUMULADO] [float] NULL ,
[CLASIFICACION] [char] (1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[PRECIOSOLP] [float] NULL ,
[PETICIONOFERTA] [varchar] (12) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[TEXTOBREVE] [varchar] (120) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[um] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[POSICIONOFERTA] [int] NULL ,
CONSTRAINT [PK_TBL_PLAN_ESCO_PB_PRECIO_SOLP_SID] PRIMARY KEY CLUSTERED
(
[CODIGOPROCESO],
[CODIGOMATERIAL],
[NUMEROSOLP],
[POSICION]
[PRECIOVALORACION]
) ON [PRIMARY] ,
CONSTRAINT [CKC_CLASIFICACION_TBL_PLAN] CHECK ([CLASIFICACION] is null or ([CLASIFICACION] = 'B' or [CLASIFICACION] = 'A') and [CLASIFICACION] = upper([CLASIFICACION])),
CONSTRAINT [CKC_MONTO_TBL_PLAN] CHECK ([MONTO] is null or [MONTO] >= 0),
CONSTRAINT [CKC_PORCENTAJEACUMULA_TBL_PLAN] CHECK ([PORCENTAJEACUMULADO] is null or [PORCENTAJEACUMULADO] >= 0),
CONSTRAINT [CKC_PRECIOVALORACION_TBL_PLAN] CHECK ([PRECIOVALORACION] is null or [PRECIOVALORACION] >= 0),
CONSTRAINT [CKC_solp] CHECK ([PRECIOSOLP] is null or [PRECIOSOLP] >= 0)
) ON [PRIMARY]
GO

y

CREATE TABLE [TBL_PLAN_ESCO_PB_MATERIAL_POR_CONCURSO_SID] (
[CODIGOPROCESO] [char] (24) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[CODIGOMATERIAL] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[DOCUMENTOCOMPRA] [varchar] (12) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[POSICION] [int] NOT NULL ,
[DESCRIPCIONMATERIAL] [varchar] (120) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[CODIGOPROVEEDOR] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[NOMBREPROVEEDOR] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[FCREACION] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[FECHACREACION] [char] (7) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[INCOTERM] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[PAISORIGEN] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[DESCRIPCIONINCOTERM] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[PRECIOULTIMACOMPRA] [float] NULL ,
[monedaultimacompra] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[PRECIOULTIMACOMPRAUSD] [float] NULL ,
[UM] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[preciostandard] [float] NULL ,
[GRUPOARTICULOS] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ORIGEN] [varchar] (13) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[FAMILIA] [varchar] (5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[FECHADESCARGADATA] [datetime] NULL ,
[PETICIONOFERTA] [varchar] (12) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[monedapreciostardard] [varchar] (4) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[texto] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
CONSTRAINT [PK_TBL_PLAN_ESCO_PB_MATERIAL_POR_CONCURSO_SID] PRIMARY KEY CLUSTERED
(
[CODIGOPROCESO],
[CODIGOMATERIAL],
[DOCUMENTOCOMPRA],
[POSICION]
) ON [PRIMARY] ,
CONSTRAINT [CKC_POSICION_TBL_PLAN] CHECK ([POSICION] is null or [POSICION] >= 0)
) ON [PRIMARY]
GO


pero al momento de insertar los datos de precios a materiales me da un error de duplicar los datos.

creo que la solucion seria poder selecionar de los registro que esten iguales el precio de valoracion mas alto, pero no logro hacer la sintaxis correcta!
si alguien puede ayudarme se lo agradeceria!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por Frida (2 intervenciones) el 10/10/2017 18:56:10
Hola, igual tengo el mismo problema, pero no entiendo a que refiere 'editor_indent' ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por Roger (1 intervención) el 12/07/2016 14:32:18
Es una solución elegante y rápida. Gracias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por VICTOR ENRIQUE MURILLO (2 intervenciones) el 20/02/2016 00:41:55
has un ROW_NUMBER() OVER (PARTITION BY COLUMNAS ORDER BY COLUMNAS)

y solo filtra en donde el resultado sea el numero 2
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por Brayan (1 intervención) el 23/04/2016 06:35:13
Buenas noches...
Disculpen tengo un problema:
tengo una tabla( tb_equipo_software) que tiene :
id_equipo_software id_equipo id_configuracion_software
------------------ 1 ---------- 1------------------3
------------------ 2 ----------- 1 ---------------- 11
-------------------3 ------------ 2------------------3
------------------ 4 ------------ 3 -----------------11

Entonces , necesito hacer una consulta que me muestre que equipo tiene el software 3 y 11 en este caso solo seria el 1
el 2 no por que solo tiene el 3 y el 3 tampoco por tener solo el 11

Select id_equipo from tb_equipo_software where id_configuracion_software in (3,11) group by id_equipo; / /Muestra todos ....1,2,3

Gracias de antemano
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Buscar dos registros en la misma tabla con varias columnas iguales

Publicado por VmurilloT (2 intervenciones) el 12/07/2016 18:59:25
Esta es una forma...

1
2
3
4
5
Select id_equipo From(
Select count(id_equipo) over (partition by id_equipo order by id_equipo) nro, id_equipo From #ejplo 
Where id_configuracion_software in (3, 11))filas
Where nro > 1
Group By id_equipo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar