2012-06-20 13 views
5

Tengo una tabla con algunas filas duplicadas. Quiero eliminar solo una fila duplicada.sql query para eliminar solo una fila duplicada

Por ejemplo, he 9 filas duplicadas, por lo que debe eliminar solo una fila y debe mostrar 8 filas restantes.

ejemplo

fecha de la llamada llamada timestampp duración

2012-06-19 10:22:45.000 165 218 155 1.9 121 
2012-06-19 10:22:45.000 165 218 155 1.9 121 
2012-06-19 10:22:45.000 165 218 155 1.9 121 
2012-06-19 10:22:45.000 165 218 155 1.9 121 

desde arriba fecha debe eliminar sólo una fila y debe mostrar 3 filas

2012-06-19 10:22:45.000 165 218 155 1.9 100 
2012-06-19 10:22:45.000 165 218 155 1.9 100 
2012-06-19 10:22:45.000 165 218 155 1.9 100 

desde arriba fecha debe eliminar sólo una fila y debería mostrar 2 filas

¿Cómo puedo hacer esto?

+0

¿Puedes formatear los datos por lo que es más fácil de leer? – codingbiz

+0

Hay cinco nombres de columna enumerados pero seis columnas en salida. ¿Y cómo cambia la última columna de 121 a 100? Si la fuente tiene dos filas con 121 y dos filas con 100, ¿eliminará dos filas o una? (En otras palabras, ¿el duplicado se basa sólo en la fecha?) –

Respuesta

1

¿Tiene una llave primaria sobre la mesa?

¿Qué hace que una fila sea un duplicado? ¿Mismo tiempo? misma fecha? todas las columnas son iguales?

Si tiene una clave primaria puede utilizar la función superior para seleccionar sólo un registro y eliminar una fila que:

Delete from [tablename] where id in (select top 1 id from [tablename] where [clause]) 
3

Si no te importa el orden de estas filas hay un comando en MySQL:

DELETE TOP (numberOfRowsToDelete) FROM db.tablename WHERE {condition for ex id = 5}; 
+0

y, por supuesto, puede usar la declaración WHERE WHERE para especificar qué fecha eliminar. – Reshi

+2

El OP solicitó una solución de SQL Server. – Spikeh

1

Para SQL Server 2005 + se puede hacer lo siguiente:

;WITH CTE AS 
(
    SELECT *, 
      ROW_NUMBER() OVER(PARTITION BY [date], calling, called, duration, [timestamp] ORDER BY 1) RN 
    FROM YourTable 
) 
DELETE FROM CTE 
WHERE RN = 2 
6

Esta solución le permite eliminar una fila de cada conjunto de duplicados (en lugar de sólo la manipulación de un solo bloque de duplicados a la vez):

;WITH x AS 
(
    SELECT [date], rn = ROW_NUMBER() OVER (PARTITION BY 
    [date], calling, called, duration, [timestamp] 
    ORDER BY [date]) 
    FROM dbo.UnspecifiedTableName 
) 
DELETE x WHERE rn = 2; 

Como acotación al margen, tanto [date] y [timestamp] son terribles opciones para nombres de columna ...

+0

cuál es el significado de; WITH x AS ?? – user2705620

+0

@ User6675636b20796f7521 Se llama una [Expresión de tabla común] (http://msdn.microsoft.com/en-us/library/ms175972.aspx). –

+0

Gracias :) esta fue una buena solución. – user2705620

0

Dado que no tengo el esquema, que había una posible solución en pasos:

  1. Aplicar un número de fila al selecto de todas las columnas
  2. Hacer un grupo de con esas columnas y eliminar la mi n (rownumber) en cada grupo

Editar:

El rownumber está en una consulta interna y tendrá el rownumber incrementando en todas las filas. En la consulta externa hago el grupo por la consulta interna y selecciono el min (número de segundo plano) para cada grupo. Como cada grupo está compuesto por filas duplicadas, elimino el min (número de barras) para cada grupo.

+1

MIN siempre será 1 para cada grupo, si está particionado por las mismas columnas. Esto significa que también eliminará las filas que * no * tengan duplicados, a menos que también agregue HAVING. Lo que lo hace aún más complejo que las soluciones ya publicadas, en mi humilde opinión. –

+0

@AaronBertrand nop, el número de rown está en una consulta interna y tendrá el número de incremento en todas las filas. En la consulta externa hago el grupo por la consulta interna y selecciono el min (número de segundo plano) para cada grupo. Como cada grupo está compuesto por filas duplicadas, elimino el min (número de barras) para cada grupo. ¿Entendiste? –

+0

Con una mejor descripción, claro, pero no coincide con su primera descripción. El código hubiera sido más útil y auto explicativo. –

0

usando LIMIT 1 le ayudará a eliminar solamente 1 ROW que coincide con su DELETE consulta:

DELETE FROM `table_name` WHERE `column_name`='value' LIMIT 1; 

ANTES:

+----------------------+ 
| id | column_name | 
+-----+----------------+ 
| 1 | value   | 
+-----+----------------+ 
| 2 | value   | 
+-----+----------------+ 
| 3 | value   | 
+-----+----------------+ 
| 4 | value   | 
+-----+----------------+ 

DESPUÉS:

+----------------------+ 
| id | column_name | 
+-----+----------------+ 
| 1 | value   | 
+-----+----------------+ 
| 2 | value   | 
+-----+----------------+ 
| 3 | value   | 
+-----+----------------+