¿Cuál es la mejor manera de eliminar todas las filas de una tabla en sql pero mantener n número de filas en la parte superior?
85
DELETE FROM Table WHERE ID NOT IN (SELECT TOP 10 ID FROM Table)
Editar:
Chris muestra un buen resultado de rendimiento ya que la consulta TOP 10 se ejecutaría para cada fila. Si esto es algo único, entonces puede que no sea tan importante, pero si es algo común, entonces lo miré más de cerca.
DELETE FROM Table WHERE ID NOT IN (SELECT id FROM (SELECT TOP 10 ID FROM Table) AS x)
para forzar a MySQL a crear una tabla temporal.Seleccionaría la (s) columna (s) de ID el conjunto de filas que desea mantener en una tabla temporal o variable de tabla. Luego, 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 "SELECT TOP 10" se ejecutará para cada fila de la tabla, lo que podría ser un gran éxito en el rendimiento. Quiere evitar hacer la misma consulta una y otra vez.
Esta sintaxis debería funcionar, según lo que enumeró como su declaración SQL original:
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
fuente
insert into #nuke(Nuke) ...
probablemente debería ser:insert into #nuke(NukeID) ...
Además, el nombre nuke es confuso porque está tratando de NO eliminar estas filas. nuke probablemente lleva el nombre del hecho de que será eliminado.Referencia futura para quienes no utilizan MS SQL.
En PostgreSQL use
ORDER BY
y enLIMIT
lugar deTOP
.DELETE FROM table WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);
MySQL - bueno ...
Supongo que todavía no.
fuente
Creo que usar una tabla virtual sería mucho mejor que una cláusula IN o una tabla temporal.
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
fuente
No sé sobre otros sabores, pero MySQL DELETE permite LIMIT.
Si pudiera ordenar las cosas de modo que las n filas que desea mantener estén en la parte inferior, entonces podría hacer un DELETE FROM table LIMIT tablecount-n.
Editar
Oooo. Creo que me gusta más la respuesta de Cory Foy , asumiendo que funciona en tu caso. Mi camino se siente un poco torpe en comparación.
fuente
Esto realmente va a ser específico del idioma, pero probablemente usaría 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 le importa el número exacto de filas, siempre hay
DELETE TOP 90 PERCENT FROM dTABLE;
fuente
Así es como lo hice. Este método es más rápido y sencillo:
Elimine todos menos los primeros n de la tabla de la base de datos en MS SQL usando el comando OFFSET
WITH CTE AS ( SELECT ID FROM dbo.TableName ORDER BY ID DESC OFFSET 11 ROWS ) DELETE CTE;
Reemplazar
ID
con la columna por la que desea ordenar. Reemplace el número despuésOFFSET
con el número de filas que desea eliminar. ElijaDESC
oASC
- lo que se adapte a su caso.fuente
Lo resolvería usando la técnica siguiente. El ejemplo espera una tabla de artículos con una identificación en cada fila.
Delete article where id not in (select top 1000 id from article)
Editar: Demasiado lento para responder mi propia pregunta ...
fuente
¿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
editar: probé ambos en el analizador de consultas, la respuesta actual es en ayunas (maldita orden por ...)
fuente
Una mejor manera sería insertar las filas que SI desea en otra tabla, soltar la tabla original y luego cambiar el nombre de la nueva tabla para que tenga el mismo nombre que la tabla anterior
fuente
Tengo un truco para evitar ejecutar la
TOP
expresión para cada fila. Podemos combinarTOP
conMAX
para obtener elMaxId
que queremos mantener. Luego, simplemente borramos todo lo que sea mayor queMaxId
.-- Declare Variable to hold the highest id we want to keep. DECLARE @MaxId as int = ( SELECT MAX(temp.ID) FROM (SELECT TOP 10 ID FROM table ORDER BY ID ASC) temp ) -- Delete anything greater than MaxId. If MaxId is null, there is nothing to delete. IF @MaxId IS NOT NULL DELETE FROM table WHERE ID > @MaxId
Nota: Es importante utilizarlo
ORDER BY
al declararMaxId
para asegurarse de que se consultan los resultados adecuados.fuente