¿Cómo eliminar las 1000 filas superiores de una tabla usando Sql Server 2008?

108

Tengo una tabla en SQL Server. Me gustaría eliminar las 1000 filas superiores. Sin embargo, probé esto, pero en lugar de simplemente eliminar las 1000 filas superiores, eliminé todas las filas de la tabla.

Aquí está el código:

delete from [mytab] 
select top 1000 
a1,a2,a3
from [mytab]
edgarmtze
fuente
8
Necesita un ORDER BY para que TOP sea significativo: vea la respuesta de @Martin Smith, que es la única de cinco que tiene esto. A veces me desespero
gbn
2
¿Quieres eliminar cualquier 1000 filas? ¿Solo seleccionado al azar? ¿O, por ejemplo, las 1000 filas más antiguas?
Nick Chammas
13
Eliminó toda la tabla porque delete from [mytab]es una declaración y select top ...es otra.
Nick Chammas
2
No necesita hacer un pedido para top, depende de por qué está haciendo TOP. Si necesita eliminar 10 millones de filas y tiene 1 GB de espacio de registro disponible, use Delete TOP (10000) From dbo.myTable (con su cláusula de selección) y continúe ejecutándolo hasta que no haya más filas para eliminar. A quién le importa si es arbitrario. Ordenar solo ralentiza la consulta.
tvanharp
1
Me doy cuenta de que esta es una pregunta antigua (en SO años), pero creo que es importante que la gente considere los comentarios de @gbn . Si bien sus comentarios no se aplican a mi situación dada (tratando de eliminar bloques de registros sin causar problemas de BLOQUEO, pero sin preocuparse realmente por el orden en que se eliminan) es muy probable que se apliquen a SU situación. Asegúrese de considerarlas antes de utilizar ciegamente las respuestas a continuación que no incluyan una cláusula ORDER BY.
Andrew Steitz

Respuestas:

196

El código que probó es de hecho dos declaraciones. A DELETEseguido de a SELECT.

No define TOPcomo ordenado por qué.

Para un criterio de orden específico, eliminar de un CTE o expresión de tabla similar es la forma más eficiente.

;WITH CTE AS
(
SELECT TOP 1000 *
FROM [mytab]
ORDER BY a1
)
DELETE FROM CTE
Martin Smith
fuente
13
Para aquellos que se preguntan por qué no puede hacerlo DELETE TOP (1000) FROM table ORDER BY column, lea esto : "Las filas a las que se hace referencia en la expresión TOP que se usan con INSERT, UPDATE, MERGE o DELETE no están organizadas en ningún orden".
Nick Chammas
3
@Magnus sí. Aunque no 2000. Podría ser posible usar una tabla derivada en 2000. No tengo una instancia para probar.
Martin Smith
2
Lo había hecho de una manera ligeramente diferente (aunque creo que el CTE podría ser más agradable de ver): ELIMINAR T1 DE (SELECCIONAR LOS 1000 PRINCIPALES * DE [MYTAB] ORDENAR POR A1) T1;
Abacus
4
@Liam: solo porque si hay alguna declaración anterior antes del CTE, esto debe terminarse con un punto y coma, por lo que agregarlo al frente de las WITHquejas de personas que no lo han hecho no lo ha hecho.
Martin Smith
86

Puede ser mejor para sql2005 + usar:

DELETE TOP (1000)
FROM [MyTab]
WHERE YourConditions

Para Sql2000:

DELETE FROM [MyTab]
WHERE YourIdField IN 
(
  SELECT TOP 1000 
    YourIdField 
  FROM [MyTab]
  WHERE YourConditions
)

PERO

Si desea eliminar un subconjunto específico de filas en lugar de un subconjunto arbitrario, debe especificar explícitamente el orden de la subconsulta:

DELETE FROM [MyTab]
WHERE YourIdField IN 
(
  SELECT TOP 1000 
    YourIdField 
  FROM [MyTab]
  WHERE YourConditions
  ORDER BY ExplicitSortOrder
)

Gracias tp @gbn por mencionar y exigir una respuesta más clara y exacta.

Oleg Dok
fuente
3
@gbn Tal vez sea inútil para ti, pero eso es exactamente lo que pide la pregunta.
Joachim Isaksson
1
@Joachim Isaksson: ve y lee sobre TOP y luego regresa. No existe TOP sin un ORDER BY en conjuntos. Alternativamente, ve y búscame una referencia canónica que demuestre que estoy equivocado ... Para ahorrarte búsquedas, sqlblog.com/blogs/alexander_kuznetsov/archive/2009/05/20/… y blogs.technet.com/b/wardpond/archive /
2007/07/19
1
@gbn No hay condiciones sobre QUÉ filas eliminar, por lo que ORDER BY en la subconsulta es inútil
Oleg Dok
1
@gbn ¿Mencionaste DÓNDE en la subconsulta? Filtre 1000 filas arbitrarias dentro de los criterios elegidos y luego elimino. ¿Escenario válido? Si. Si agrego ORDER BY NEWID () o lo que sea, no cambia nada, todavía elimino 1000 filas filtradas por criterios elegidos
Oleg Dok
8
@gbn En caso de que esté buscando un uso válido de TOP sin ORDER BY: lo que me trajo aquí es que necesito eliminar todas las filas que coinciden con algunos criterios pero, por razones de rendimiento, no quiero que elimine más de 10,000 filas a la vez. No me importa qué filas elimine, ya que ejecutaré el comando nuevamente en algún intervalo hasta que todas esas filas desaparezcan.
Richiban
6
delete from [mytab]
where [mytab].primarykeyid in
(
select top 1000 primarykeyid
from [mytab]
)
Jason Dam
fuente
4
Inútil: TOP sin un ORDER BY da filas arbitrarias
gbn
4
@gbn Tal vez sea inútil para ti, pero eso es exactamente lo que pide la pregunta.
Joachim Isaksson
3
@gbn No he dicho que exista un orden de clasificación predeterminado o que la consulta sea útil de alguna manera, solo le recordé que la pregunta no pedía uno, así que, ¿qué sugeriría ordenar?
Joachim Isaksson
2
@gbn No sé por qué eres tan hostil con todos por algo que es un punto de partida. No pretendo que mi respuesta sea el fin de todo, es simplemente una sugerencia para ayudar a alguien. Creo que la importancia son las claves que vienen de la subconsulta aquí.
Jason Dam
2
Esto puede ser todo lo que busca el autor de la pregunta. Solo agregaría una nota para que los demás lean para enfatizar que no se garantiza que las filas eliminadas por tal declaración estén en ningún orden.
Nick Chammas
3
SET ROWCOUNT 1000;

DELETE FROM [MyTable] WHERE .....
Joe Bourne
fuente
2
Cuando se trata de solo 1000 filas, ¿realmente importa? Si fueran 100,000,000 filas, entonces sus puntos podrían ser válidos, pero para solo 1000 filas, esta es, con mucho, la solución más simple propuesta hasta ahora para SQL 2008.
Joe Bourne
1

Es rápido. Intentalo:

DELETE FROM YourTABLE
FROM (SELECT TOP XX PK FROM YourTABLE) tbl
WHERE YourTABLE.PK = tbl.PK

Reemplazar YourTABLEpor el nombre de la tabla, XXpor un número, por ejemplo 1000, pkes el nombre del campo de clave principal de su tabla.

Hamed elahi
fuente
De hecho, está creando dos tablas a partir de una y luego eliminando donde se unieron. Funciona bien cuando desea eliminar los registros más antiguos (o más nuevos) de una tabla, ya que puede ordenarlos de forma ascendente primero. Microsoft acepta este t-sql (y es rápido).
Tequila