2017-03-14 1 views
1

제 상황은 예측할 수없는 SQL 문이 프로그램에 주어지고 그 위에 페이지 매김을해야한다는 것입니다. 마지막 SQL 문은 하나 다음과 유사 할 것입니다 :SQL 서버 - 주문이없는 페이지 매김

SELECT * FROM (*Given SQL Statement*) b OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY; 

여기서 문제는 * 지정된 SQL 문은 "예측할 수 있다는 것이다 그것은 나 나는를 변경할 수 없습니다입니다 절에 의해 순서를 포함하거나 포함하지 않을 수있다.. 이 SQL 문에 대한 쿼리 결과 및 페이지 매김을 수행해야합니다. 인터넷에서 솔루션을 검색했지만 모든 사용자가 order by 절에서 기본 키와 같은 임의의 열을 사용하도록 제안했습니다.

+0

참조 http://stackoverflow.com/questions/10064532/the-order-of-a-sql-select-statement-with-order-by-clause 그래서 ORER BY를 추가해야합니다. 당신은 GIVEN SQL Statment를 점검하고 nmot가 지정된 경우 첫 번째 열에 의해 ORDER BY 1을 추가 할 수 있다고 생각합니다. – AntDC

+0

"이 SQL 문의 쿼리 결과를 변경할 수 없습니다."라고 말하면 변경하지 못한다고 말합니다 결과가 나오기 전에 진술을 얻었습니까? 원하는 결과를 얻기 위해 시스템에서 변경 될 수있는 것과 불가능할 수있는 것을 정확히 설명해야합니다. 데이터 흐름의 어느 시점에 관여 했습니까? 데이터베이스에 액세스 할 수 있습니까? 아니면 한 곳에서 다른 곳으로 데이터가 흐르고 있습니까? 기본적으로 시스템 아키텍처는 무엇입니까? – Tony

+0

답장을 보내 주셔서 감사합니다. 원래 결과에 영향을 미치지 않고 실행 전에 명령문을 변경할 수 있습니다. 문제는 그 진술을 알 수 없다는 것입니다. 나는 그것을 바꿀 수있다. 나는 변화의 영향을 확신하지 못한다. 이 질문에는 복잡한 시스템 아키텍처가 포함되어 있지 않습니다. 필자는 애플리케이션에서받은 모든 SQL 문에 페이지 매김을 수행하고 그 결과를 출력 할 책임이 있습니다. –

답변

2

짧은 대답은 할 수 없거나 적어도 제대로 수행 할 수 없다는 것입니다.

문제는 SQL Server (또는 모든 RDBMS)가 order by 절없이 쿼리에서 반환 된 레코드의 순서를 보장하지 않으며 보장 할 수 없다는 것입니다.
이렇게하면 해당 쿼리에서 페이징을 사용할 수 없습니다.

;WITH cte (a, b) 
AS 
(
    SELECT 1, 'a' 
    UNION ALL 
    SELECT 1, 'b' 
    UNION ALL 
    SELECT 2, 'a' 
    UNION ALL 
    SELECT 2, 'b' 
) 

SELECT * 
FROM cte 
ORDER BY a 
: 빠른 예 - 당신이 당신의 결과 집합에서 여러 번 나타나는 열 order by 절을 사용하는 경우
은 더 나아가, 결과 세트의 순서는 여전히 말했다 열의 값 그룹 내에서 보장되지

두 결과 집합은 유효하며, 당신은 당신이 얻을 것이다 무엇인지 미리 알 수 없습니다

a b 
----- 
1 b 
1 a 
2 b 
2 a 

a b 
----- 
1 a 
1 b 
2 a 
2 b 

(물론, 다른 종류를 얻을 수 있습니다)

1

홍보를 여기서 oblem은 * 주어진 SQL 문이 "예측할 수 없다는 것입니다. order by 절을 포함 할 수도 있고 포함하지 않을 수도 있습니다.

내부 쿼리 (예기치 않은 SQL 문)에는 순서가 포함되어서는 안되며, 포함 된 경우에도 순서가 보장되지 않습니다. 아마 끔찍하게 비효율적 내가 제안하려고 해요 것입니다 :

것은 보장 순서를 얻으려면, 당신은 결정적으로 결과 column.for 일부에 의해 주문해야 주문한 열/열

주의 사항
+1

좋은 지적. 실제로 그것은'top','offset' 또는'for xml'을 포함하지 않는 한'order by' 절을 포함 할 수 없습니다. 파생 된 테이블로 사용되기 때문입니다. 오류를 반환합니다 - "ORDER BY 절은 TOP, OFFSET 또는 FOR XML이 지정되지 않은 경우보기, 인라인 함수, 파생 테이블, 하위 쿼리 및 공통 테이블 식에서는 유효하지 않습니다." 알았어. –

+0

. 나는 네가 의미하는 것이 있다고 생각해. 따라서 "주어진 SQL 문"위에 하나 이상의 레이어를 추가하는 대신 명령문에 포함 된 경우 order by 절을 검색해야합니다. 그렇지 않다면 간단히 추가하십시오. 그럴 경우 Offset을 추가하십시오. 맞습니까? –

+0

예, 맞습니다. –

0

고유해야합니다 실제로 프로젝트 리더에게 돌아가서 정렬되지 않은 쿼리의 페이지 매김이 수행되어서는 안된다고 말할 때만 사용해야합니다. 그 말은 ...

귀하의 의견은 당신이 SQL 문을 실행하기 전에 변경할 수 있다고 말합니다.

이후의 페이지 매김 순서에 사용할 행 수 필드를 추가하여 임시 테이블에 원래 쿼리의 결과를 쓸 수 있습니다.

따라서 원래 순서가 유지되고 페이지 매김을 할 수 있습니다.

물론 첫 번째 페이지 매김이 필요한 이유는 많은 양의 데이터를 클라이언트 응용 프로그램에 보내지 않는 것입니다. 이렇게해도 데이터가 임시 테이블로 복사되므로 행 크기와 개수에 따라 매우 느려질 수 있습니다.

페이지 크기가 클라이언트의 SQL 문에 포함되어 있다는 문제가 있습니다. 구문을 파싱하여이를 찾아내는 것이 까다로울 수 있습니다.