Sql Server 2008을 사용하여 테이블에서 상위 1000 개 행을 삭제하는 방법은 무엇입니까?


108

SQL Server에 테이블이 있습니다. 여기에서 상위 1000 개 행을 삭제하고 싶습니다. 그러나 이것을 시도했지만 상위 1000 행을 삭제하는 대신 테이블의 모든 행을 삭제했습니다.

다음은 코드입니다.

delete from [mytab] 
select top 1000 
a1,a2,a3
from [mytab]

8
당신은 메이크업의 TOP 의미에 의해 주문을 필요로하십시오이다 @Martin 스미스의 대답은 참조 이이 다섯 중 하나. 나는 때때로 절망
GBN

2
당신은 삭제 하시겠습니까 모든 1000 개 행을? 그냥 무작위로 선택 했나요? 또는 예를 들어 가장 오래된 상위 1000 개 행?
Nick Chammas 2012 년

13
delete from [mytab]하나의 문이고 select top ...다른 문 이기 때문에 모든 테이블을 삭제했습니다 .
Nick Chammas 2012 년

2
TOP을 위해 주문할 필요가 없습니다. TOP을하는 이유에 따라 다릅니다. 1,000 만 개의 행을 제거해야하고 1GB의 로그 공간을 사용할 수있는 경우 Delete TOP (10000) From dbo.myTable (select 절 포함)을 사용하고 삭제할 행이 더 이상 없을 때까지 계속 실행합니다. 자의적이라면 누가 신경 쓰겠습니까? 정렬하면 쿼리 속도가 느려질뿐입니다.
tvanharp

1
나는 이것이 고대의 질문이라는 것을 알고 있지만 사람들이 @gbn의 코멘트를 고려하는 것이 중요 하다고 생각합니다 . 그의 의견은 내 주어진 상황에 적용되지 않지만 (LOCK 문제를 일으키지 않고 레코드 블록을 삭제하려고 시도하지만 삭제 순서는 신경 쓰지 않음) 귀하의 상황에 적용될 가능성이 큽니다. ORDER BY 절이 포함되지 않은 아래 답변을 맹목적으로 활용하기 전에이를 고려하십시오.
Andrew Steitz 2016-08-22

답변:


196

시도한 코드는 사실 두 개의 진술입니다. A DELETE다음에 SELECT.

당신은 TOP무엇에 의해 주문 된 것으로 정의하지 않습니다 .

특정 순서 기준의 경우 CTE 또는 유사한 테이블 식에서 삭제하는 것이 가장 효율적인 방법입니다.

;WITH CTE AS
(
SELECT TOP 1000 *
FROM [mytab]
ORDER BY a1
)
DELETE FROM CTE

13
당신이 할 수없는 이유를 궁금해 사람들을 위해 DELETE TOP (1000) FROM table ORDER BY column, 이 읽기 : "INSERT와 함께 사용 된 TOP 식에서 참조하는 행이, UPDATE가, 병합, 또는 DELETE가 어떤 순서로 배열되지 않습니다."
Nick Chammas

3
@Magnus 예. 하지만 2000 년은 아닙니다. 2000 년에 파생 된 테이블을 사용하는 것이 가능할 수 있습니다. 테스트 할 인스턴스가 없습니다.
Martin Smith


2
약간 다른 방법을 사용했습니다 (CTE가보기에 더 좋을 것 같지만) : DELETE T1 FROM (SELECT TOP 1000 * FROM [MYTAB] ORDER BY A1) T1;
Abacus

4
@Liam-CTE 앞에 선행 진술이있는 경우 세미콜론으로 종료해야하므로이를 WITH수행하지 않은 사람들의 불만 사항을 선점 앞에 추가합니다 .
Martin Smith

86

sql2005 +가 다음을 사용하는 것이 더 나을 수 있습니다.

DELETE TOP (1000)
FROM [MyTab]
WHERE YourConditions

SQL2000의 경우 :

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

그러나

임의의 하위 집합 대신 특정 행 하위 집합 을 삭제하려면 하위 쿼리 순서를 명시 적으로 지정해야합니다.

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

더 명확하고 정확한 답변을 언급하고 요구해 주신 tp @gbn에게 감사드립니다.


3
@gbn 아마도 당신에게는 쓸모가 없지만 여전히 질문이 요구하는 것입니다.
Joachim Isaksson

1
@Joachim Isaksson : 가서 TOP에 대해 읽어보고 돌아 오세요. 세트에서 ORDER BY가없는 TOP과 같은 것은 없습니다. 또는 내가 틀렸다는 것을 증명하는 표준 참조를 찾아보세요 ... 검색을 절약하려면 sqlblog.com/blogs/alexander_kuznetsov/archive/2009/05/20/…blogs.technet.com/b/wardpond/archive / 2007 / 07 / 19 /…
gbn

1
하위 쿼리가 쓸모가에서 ORDER BY 있도록 행이 삭제되는 대해 어떤 조건 없음 @gbn
올렉 독도

1
@gbn 하위 쿼리에서 WHERE를 언급 했습니까? 선택한 기준 내에서 1000 개의 임의의 행을 필터링 한 다음 삭제합니다. 유효한 시나리오? 예. 내가 ORDER BY NEWID를 (추가) 또는 아무것도 변경되지 어떤 경우에 - 나는 아직도 선택이 끝난 기준으로 필터링 1000 개 행을 삭제
올렉 독도

8
@gbn ORDER BY없이 TOP의 유효한 사용을 찾고있는 경우 : 여기에 저를 가져온 것은 일부 기준과 일치하는 모든 행을 삭제해야하지만 성능상의 이유로 10,000 개 이상의 행을 삭제하고 싶지 않다는 것입니다. 한 번에. 모든 행이 사라질 때까지 일정 간격으로 명령을 다시 실행하므로 삭제되는 행은 상관 없습니다.
Richiban 2014 년


6
delete from [mytab]
where [mytab].primarykeyid in
(
select top 1000 primarykeyid
from [mytab]
)

4
쓸모 없음 : ORDER BY가없는 TOP은 임의의 행을 제공합니다
gbn

4
@gbn 아마도 당신에게는 쓸모가 없지만 여전히 질문이 요구하는 것입니다.
Joachim Isaksson 2012 년

3
@gbn 기본 정렬 순서가 있거나 쿼리가 어떤 식 으로든 유용하다고 주장하지 않았습니다. 질문이 하나를 요청하지 않았으므로 무엇을 주문할 것을 제안합니까?
Joachim Isaksson

2
@gbn 왜 당신이 시작점 인 무언가에 대해 모든 사람에게 그렇게 적대적인지 모르겠습니다. 나는 내 대답이 끝이라고 주장하지 않으며, 누군가를 돕기위한 제안 일뿐입니다. 중요한 것은 여기의 하위 쿼리에서 반환되는 키라고 생각합니다.
Jason Dam

2
이것이 질문자가 찾고있는 전부일 수 있습니다. 나는 다른 사람들이 그러한 명령문에 의해 삭제 된 행이 어떤 순서로든 보장되지 않는다는 것을 강조하기 위해 읽는 메모를 추가 할 것입니다.
Nick Chammas

3
SET ROWCOUNT 1000;

DELETE FROM [MyTable] WHERE .....

2
1000 개의 행만 다룰 때 정말 중요합니까 ?? 이 100,000,000 행했다면 다음 포인트는 유효 할 수 있지만 단지 1000 행에 대해,이 간단한 솔루션은 SQL 2008을 위해 지금까지 제안 된 지금까지
조 Bourne의

1

빠릅니다. 시도 해봐:

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

YourTABLE테이블 이름으로 바꾸기 ( XX예 : 1000) pk는 테이블의 기본 키 필드 이름입니다.


효과적으로 하나에서 두 개의 테이블을 만든 다음 조인 된 위치를 삭제합니다. 먼저 오름차순으로 정렬 할 수 있기 때문에 테이블에서 가장 오래된 (또는 최신) 레코드를 삭제하려는 경우 잘 작동합니다. 이 t-sql은 Microsoft에서 허용하며 빠릅니다.
Tequila
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.