2008-09-05 22 views

Respuesta

61
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table) 

Editar:

Chris aporta un buen rendimiento golpeado desde el 10 TOP consulta se ejecuta para cada fila. Si esto es una cosa de una sola vez, entonces puede no ser tan importante, pero si es algo común, entonces lo miré más de cerca.

+3

Si alguien comúnmente necesita eliminar todas las n filas, diría que tienen problemas más importantes de los que preocuparse. –

+4

Solo una nota de que puede resolver el problema de rendimiento de la subconsulta creando manualmente una tabla temporal (asumiendo que esta es una operación poco frecuente) o escribiendo la consulta como 'DELETE FROM Tabla WHERE ID NOT IN (SELECCIONE ID FROM (SELECCIONE IDENTIFICACIÓN DE TOP 10 Tabla) AS x) 'forzar a MySQL a crear una tabla temporal. –

+0

Gracias. Eso fue un salvavidas :) – Si8

2

No sé sobre otros sabores pero MySQL DELETE permite LIMITAR.

Si pudiera ordenar cosas para que las n filas que desea mantener estén en la parte inferior, entonces podría hacer un BORRAR DE la tabla LIMIT tablecount-n.

Editar

Oooo. Creo que me gusta Cory Foy's responder mejor, suponiendo que funcione en su caso. Mi manera se siente un poco torpe en comparación.

0

Lo resolvería usando la técnica a continuación. El ejemplo espera un artículo tabla con un id en cada fila.

Delete article where id not in (select top 1000 id from article) 

Editar: Demasiado lento para responder a mi propia pregunta ...

29

Me gustaría seleccionar la columna (s) de identificación del conjunto de filas que desea guardar en una tabla temporal o variable de tabla. A continuación, elimine todas las filas que no existen en la tabla temporal. La sintaxis mencionada por otro usuario:

DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table) 

Tiene un problema potencial. La consulta "SELECCIONAR TOP 10" se ejecutará para cada fila de la tabla, lo que podría ser un gran golpe de rendimiento. Desea evitar hacer la misma consulta una y otra vez.

Esta sintaxis debe trabajar, en base de lo que aparece como su estado original de SQL:

create table #nuke(NukeID int) 

insert into #nuke(Nuke) select top 1000 id from article 

delete article where not exists (select 1 from nuke where Nukeid = id) 

drop table #nuke 
+2

'insert into #nuke (Nuke) ...' probablemente debería ser: 'insert into #nuke (NukeID) ...' También el nombre nuke es confuso porque estás tratando de NO eliminar estas filas. nuke probablemente se nombre por el hecho de que se eliminará. –

0

refactorizado?

Delete a From Table a Inner Join (
    Select Top (Select Count(tableID) From Table) - 10) 
     From Table Order By tableID Desc 
) b On b.tableID = A.tableID 

edición: ellos trató tanto en el analizador de consultas, la respuesta actual se ayunó (orden maldita por ...)

0

mejor manera sería insertar las filas que desea en otra tabla, suelte la tabla original y luego cambie el nombre de la nueva tabla para que tenga el mismo nombre que la tabla anterior

+0

¿Por qué es eso mejor? ¿Más rápido? Requiere un par de comandos adicionales para lograr. – MeanGreen

6

Referencia futura para los usuarios que no usan MS SQL.

En PostgreSQL use ORDER BY y LIMIT en lugar de TOP.

DELETE FROM table 
WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n); 

MySQL - bien ...

error - Esta versión de MySQL todavía no soporta 'LÍMITE & EN/ALL/ANY/SOME subconsulta'

Todavía no supongo.

1

Esto realmente va a ser específico del idioma, pero es probable que utilice algo como lo siguiente para el servidor SQL.

declare @n int 
SET @n = SELECT Count(*) FROM dTABLE; 
DELETE TOP (@n - 10) FROM dTable 

si no se preocupan por el número exacto de filas, siempre hay

DELETE TOP 90 PERCENT FROM dTABLE; 
+1

Ninguno de estos funciona. La pregunta pregunta cómo mantener solo las primeras N filas en una tabla. Ambos ejemplos mantienen solo las N filas inferiores. – Chris

+0

Funciona bien en MSSQL. ¿Simplemente agrega una clasificación para eliminar la parte inferior en lugar de la parte superior? – MeanGreen

2

Creo usando una tabla virtual sería mucho mejor que una tabla en la cláusula o temp.

DELETE 
    Product 
FROM 
    Product 
    LEFT OUTER JOIN 
    (
     SELECT TOP 10 
      Product.id 
     FROM 
      Product 
    ) TopProducts ON Product.id = TopProducts.id 
WHERE 
    TopProducts.id IS NULL 
Cuestiones relacionadas