SELECT ROW_NUMBER ()가 생성 된 행 번호별로 정렬 된 결과를 반환하도록 보장됩니까?


10

예를 들어 SQL 쿼리를 고려하십시오.

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC)
FROM
   [FooTable] AS A

여기서는 A. [이름]별로 정렬 된 결과가 반환됩니다. ROW_NUMBER 함수에 정의 된 정렬 열을 다른 열로 변경하면 결과가 해당 열을 기준으로 다시 정렬됩니다.

행 번호가 행에 할당 될 것으로 기대했지만 행이 동일한 기준으로 정렬되어 다시 오는 것을 기대하지 않았습니다. 이는 쿼리 실행 방법 (SQL Server 2008 R2의 경우)의 부작용 일 뿐입니 까, 아니면이 동작이 보장됩니까? (나는 그런 보증에 대한 언급을 찾을 수 없었습니다).


10
보장은 없습니다. 이제까지. SQL Server에 주문 방법을 알려주지 않으면 원하는 순서대로 데이터를 자유롭게 반환 할 수 있습니다. 주문을 생략하면 주문에 신경 쓰지 않는다고 SQL Server에 알립니다. 보증을 원하면 ORDER BY 절을 이미 입력하십시오.
Aaron Bertrand

해당 order-by 절이 매우 복잡하므로 복사하면 코드 유지 관리 밸러스트와 미래의 결함 가능성이 높아 지므로 묻는 이유가 있습니다. 다른 대안은 SQL 표준이 암시 적 정렬 순서를 정의한 경우 피할 수 있다고 생각한 사소한 리팩토링입니다. 어쨌든 나는이 점을 다루는 공식적인 문서가 있다면 관심이있었습니다.
redcalx

1
왜 그 질문을하지 않습니까?
Aaron Bertrand

답변:


14

질문을했다면 실제로 다음과 같은 질문을해야한다고 생각합니다.

ROW_NUMBER()복잡한 ORDER BY표현 을 반복하지 않고 어떻게 주문할 수 있습니까?

ROW_NUMBER()표현식 의 별명을 작성하고 별명을 사용하여 정렬 하도록 지시 할 수 있습니다 .

SELECT
   A.[Name],
   rn = ROW_NUMBER() OVER (ORDER BY <complex expression>)
FROM
   dbo.[FooTable] AS A
ORDER BY rn;

이제 식을 한 곳에서만 변경하면 결과 정렬은 식을 반복하지 않고도 해당 식을 기반으로합니다.


6
실제로 repeating the complex ORDER BY expression출력이 ROW_NUMBER () 순서로 나올 것이라고 보장하지는 않습니다. ORDER BY 절의 열이 고유 키를 형성하지 않으면
孔夫子

22

절대적으로하지. 증명:

SELECT
   A.[Name],
   ROW_NUMBER() OVER(ORDER BY A.[Name] ASC),
   ROW_NUMBER() OVER(ORDER BY A.[Name] DESC)
FROM
   [FooTable] AS A

SQL에서 주문을 보장하는 유일한 방법은 요청 ORDER BY하고 결과 자체에 사용 하는 것입니다.


확인을 하나 더 추가하겠습니다. 하나의 ROW_NUMBER () 절만 지정하면 결과가 정렬됩니다.
redcalx

22
SQL 주문을 보장하는 유일한 방법은 요청하는 것입니다
Remus Rusanu

0

실제로 (오래된) 질문은 파티션을 부분적으로 포함하도록 확장 될 수 있습니다. 먼저 파티션에 의한 암시 적 순서 있고 그다음 부분적으로 순서 가있는 것처럼 보입니다.

따라서 일부 사람들이 row_number를 할당하고 순서에 사용하는 것만 큼 간단하지 않습니다.

파티션별로 절을 추출하는 중첩 된 SQL도 필요합니다 (물론 단순히 반복하지 않으려는 경우)

경험적으로 우리는 주문의 마지막 줄을 암시 적으로 얻는 것처럼 보입니다.

Select
  <field-list>, 
  rn=Row_Number() over(partition by <PartionClause>) order by <OrderClause>
from ....
Order by <PartionClause> asc, rn asc

그러나 우리에게 부족한 것은 그것이 항상 보유하고 있다는 증거 나 보증입니다.

(행에 다수의 Row_Number () 호출이있는 경우 주문을 한 것 같습니다.)

ALSO 참고가 명시 적으로 추가하는 경우 가 순서를 명확하게 최종 정렬 단계를 보여주고, 이미 소트 세트를 정렬하는 종류의 최악의 케이스 인 실행 계획, 따라서 그것은 실질적으로 더 오래 걸립니다 주문 이없는 이상


1
이것은 실제로 질문에 대한 답이 아니며, 받아 들여진 대답과 고도로 찬성 된 대답에 모두 동의하지 않는 것 같습니다.
Erik Darling

나는 내 답변이 답변보다 더 많은 의견에 동의합니다. 잘 받아 들여진 대답은 우리가 명령을 더 잘 믿지 않는다는 것을 제외하고는 실제로 답이 아닙니다. 그리고 그것이 문제였습니다. 실행 계획에 따르면 실제로 정렬을 수행하고 명시 적 순서를 추가하면 두 번째 정렬을 얻습니다. 그러나 이것은 증거가 아니며, 경험적 지식의 일부일뿐입니다
Eske Rahn

(물론 테이블에 액세스하는 데 사용할 수있는 적절한 색인이없는 경우에만 정렬을 수행하지만 명시 적으로 주문을 제공하는 데 비용이 들지 않음을 보여주기 위해 추가했습니다)
Eske Rahn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.