SQL Server - Borrar Duplicados

 
Vista:
sin imagen de perfil
Val: 55
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Borrar Duplicados

Publicado por ANTONIO (28 intervenciones) el 06/10/2020 16:59:12
Hola tengo un problema, en la siguiente consulta vienen registros duplicados (todas las columnas completamente iguales en muchos casos), si hago un Count de registros muchos vienen a 1 y otros con 2 duplicados, el casos es que en el caso de 2 duplicados solo debo quedarme con 1 de ellos (manteniendo los que ya me venían unicos por supuesto). He intentado varias opciones pero no termina de Deletearlos.
Esta es la consulta que me entraría y he de depurar :

1
2
3
4
5
6
SELECT , MPrecios.IdLinea, MPrecios.IdItinerario, MPrecios.IdOrigen, MPrecios.IdDestino, MPrecios.IdProducto
FROM MPrecios
INNER JOIN MLineas ON MLineas.IdLinea = MPrecios.IdLinea
INNER JOIN MParadas AS pOrig ON pOrig.IdParada = MPrecios.IdOrigen INNER JOIN MParadas AS pDest ON pDest.IdParada = MPrecios.IdDestino
INNER JOIN MItinerarios on MItinerarios.IdItinerario = MPrecios.IdItinerario INNER JOIN MProductos ON MProductos.IdProducto = MPrecios.IdProducto
WHERE MPrecios.Borrado = 0 AND MPrecios.IdRegActivo IS NULL AND FechaValidoIni <= GETDATE() AND(FechaValidoFin IS NULL OR FechaValidoFin > GETDATE()) AND MPrecios.Prohibido = 0  AND MPrecios.IdLinea = 1994

Como ya digo si al select le agrego COUNT(*) AS Reg y agrupo me salen en este caso 944 unicos y 1379 con 2
¿podríais ayudarme? muchas gracias
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

Borrar Duplicados

Publicado por anonymous (19 intervenciones) el 06/10/2020 17:09:20
Pues lo ideal es primero realizar un group by por las columnas del caso para detectar los duplicados, una vez se detecten se hace un barrido con un loop y se obvia el primer registro y se le aplica delete a los demás.

Y/o aplicar un query como este:

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
DELETE A
FROM MyTable A
INNER JOIN
(
        SELECT ROW_NUMBER()OVER(PARTITION BY a.col1,
        a.Col2
        ORDER BY a.Col1,a.Col2)AS POS,
        a.rowID,
        a.Col3
        FROM MyTable A
        JOIN
        (
            Select
            Col1,
            Col2,
            COUNT(*) AS CONTADOR
            from MyTable
            group by Col1,
            Col2
            HAVING COUNT(*) > 1
        ) TB
        ON A.col1 = TB.col1
        AND A.col2 = TB.col2
) TB_2
ON
a.ROWID = tb_2.ROWID
and tb_2.pos > 1

En cualquier caso recomiendo crear una tabla temporal y efectuar backup, antes de ir a borrar cosas
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 55
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Borrar Duplicados

Publicado por ANTONIO (28 intervenciones) el 06/10/2020 19:27:08
La segunda opción no me funciona no entiendo la opción rowID, no se donde hay que declararla en en esta ocasión (invalid column name)
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 Plutarco
Val: 122
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Borrar Duplicados

Publicado por Plutarco (46 intervenciones) el 08/10/2020 15:50:20
Buenos días, si me permiten:

El rowid al que se refiere Jorge (creo yo) es un indetificador único que debieras tener en tus tablas, un campo tipo identity que funciona como identificador en una tabla, si tu tienes esa columna entonces tienes un diferenciador entre renglones aunque estos esten duplicados, es decir:

Si tienes una tabla con 3 columnas y 2 datos donde los valores de los datos son iguales, sql no tiene un diferenciador para eliminar solo un registro:
Col1 Col2 Col3
valorc_1 Valor_c2 Valor_c2
valorc_1 Valor_c2 Valor_c2

Pero si metes una columna como identificador:
rowid Col1 Col2 Col3
1 valorc_1 Valor_c2 Valor_c2
2 valorc_1 Valor_c2 Valor_c2


Ahora ya puedes hacer un Delete From ... Where rowid = 2

Perdón por la intromisión, mi humilde opinión es que eso es lo que te quieren decir.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 55
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Borrar Duplicados

Publicado por ANTONIO (28 intervenciones) el 08/10/2020 17:01:28
No hay nada que perdonar todo lo contrario.
Exacto, es que el problema como decía es que lo que me encuentro es con una consulta que no tiene indices, son muchos identificadores eso sí, pero el problema es que las 5 columnas se repiten en ocasiones 2, 3 veces o más. Efectivamente el rowid añade la columna que identificaría cuál quitar, en este caso entiendo que tendría que hacer un (if) por ejemplo que a igual registro me borre todos aquellos cuyo rowid sea mayor que 2.

Entiendo que sería así ¿verdad?

Muchas 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
Imágen de perfil de Isaias
Val: 3.250
Oro
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Borrar Duplicados

Publicado por Isaias (4558 intervenciones) el 08/10/2020 17:30:11
Pongo un ejemplo de codigo para la version 2005 y superior

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
CREATE TABLE #temp
(
code int,
iencucod int,
duracion int
)
 
INSERT INTO #temp values (1,2999,1062)
INSERT INTO #temp values (1,2999,1062)
INSERT INTO #temp values (1,2999,1062)
INSERT INTO #temp values (1,2999,1062)
INSERT INTO #temp values (1,2999,1062)
INSERT INTO #temp values (1,2999,1062)
INSERT INTO #temp values (2,2999,610)
INSERT INTO #temp values (3,2999,34)
INSERT INTO #temp values (4,6170,447)
INSERT INTO #temp values (5,15729,1148)
INSERT INTO #temp values (6,15729,241)
INSERT INTO #temp values (6,15729,241)
INSERT INTO #temp values (6,15729,241)
INSERT INTO #temp values (7,15729,53)
INSERT INTO #temp values (8,38314,1029)
INSERT INTO #temp values (8,38314,1029)
INSERT INTO #temp values (8,38314,1029)
INSERT INTO #temp values (9,38314,256)
 
select * from #temp
 
 
WITH CTE (code, iencucod, duracion, DuplicateCount)
AS
(
SELECT code,iencucod, duracion,
ROW_NUMBER() OVER(PARTITION BY code, iencucod, duracion ORDER BY code,iencucod, duracion) AS DuplicateCount
FROM #temp
)
DELETE
FROM CTE
WHERE DuplicateCount > 1
GO
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 55
Ha mantenido su posición en SQL Server (en relación al último mes)
Gráfica de SQL Server

Borrar Duplicados

Publicado por ANTONIO (28 intervenciones) el 09/10/2020 09:20:12
Genial, fantastico ejemplo, me funciona. Muchas 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