2016-09-24 2 views
0

자료를 동일한 쿼리와 다른 결과를 가질 수있는 기회가된다 :한계와 쿼리 및 오프셋 오프셋 포스트 그레스 문서에 포스트 그레스에

이 시작하기 전에 많은 행이 행을 반환하는 것을 건너 말한다 OFFSET.

는 내가 기본가에 영향이 SQL 쿼리에/더 정렬 논리가 정렬하지 않는 경우, 기본 정렬을 사용하는 경우 동일한 쿼리와 다른 결과를 얻을 수있는 기회가 궁금해 것을 고려가 있습니까?

+0

"기본 정렬"이란 무엇입니까? 그런 건 들어 본 적이 없어요. –

+0

죄송합니다. 어떤 정렬도 추가하지 않은 쿼리가 추가되었습니다. 즉. 표에서 *를 선택하십시오. – froi

답변

1

댓글이 너무 깁니다.

OFFSETLIMIT은 결과 집합이 쿼리에서 반환 될 때 실제로 쿼리 처리의 마지막 단계로 적용됩니다.

쿼리에 ORDER BY이없는 경우 쿼리 결과는 중첩되지 않음 순서입니다. 사실, 결과의 순서는 쿼리 실행마다 다를 수 있습니다.

심지어 ORDER BY이 있더라도 행이 동일한 키 값을 가질 때 불확정 오더가 발생합니다. SQL의 정렬은 안정적이지 않습니다 (안정적인 정렬은 항상 같은 순서로 행을 반환합니다). 그 이유는 간단합니다 : SQL 테이블은 으로 정렬되지 않았기 때문에 세트로되어 있기 때문에 안정적인 정렬을 정의하는 "자연스러운"정렬은 없습니다.

일관되게 주문 된 데이터를 신경 쓰는 경우 항상 ORDER BY을 사용해야합니다. 그리고 키 조합이 각 행을 고유하게 정의하는지 확인해야합니다. 그렇지 않은 경우 기본 키를 ORDER BY의 마지막 키로 사용하십시오.

0

기본적으로 다른 결과를 얻으려면 (순서가 없음을 의미) SQL이 1에서 다른 쿼리로 실행을 최적화하는 방법을 기반으로하는지 확인해야하지만 일반적으로 삽입 또는 삭제와 같은 DML 작업이 수행 될 것이라고 추측합니다 차별화 된 결과의 가장 큰 원인.

CREATE TABLE ExampleTable (Id INTEGER, Letter CHAR(1)); 

INSERT INTO ExampleTable (Id,Letter) VALUES (1,'A'),(5,'C'),(3,'B'); 


SELECT * 
FROM 
    ExampleTable 
ORDER BY 1  
LIMIT 1 OFFSET 1 
; 

SELECT 'Example 1' as Example, * 
FROM 
    ExampleTable 
ORDER BY 1  
LIMIT 1 OFFSET 1; 

INSERT INTO ExampleTable (Id, Letter) VALUES (2,'D'); 

SELECT * 
FROM 
    ExampleTable 
ORDER BY 1  
LIMIT 1 OFFSET 1 
; 

SELECT 'Example 1' as Example, * 
FROM 
    ExampleTable 
ORDER BY 1  
LIMIT 1 OFFSET 1; 

첫 번째 결과는 내가 5,c & 5,C를 얻고 있었다 추가 열 이것을 실행할 때 3,b초 결과가 2,D 나중에입니다. PostresSQL은 추가 전용 값이없는 경우 INTEGER에 대한 쿼리를 최적화합니다. 따라서 기본값 (순서 없음)이 쿼리와 다를 수 있습니다.

CREATE TABLE ExampleTable2 (Id INTEGER, Letter CHAR(1)); 

INSERT INTO ExampleTable2 (Id,Letter) VALUES (1,'A'),(3,'C'),(4,'D'); 

SELECT * 
FROM 
    ExampleTable2 
ORDER BY Letter 
LIMIT 1 OFFSET 1 
; 

INSERT INTO ExampleTable2 (Id,Letter) VALUES (2,'B'); 

SELECT * 
FROM 
    ExampleTable2 
ORDER BY Letter 
LIMIT 1 OFFSET 1 
; 

첫 번째 결과는 3,C 될 것입니다하지만 두 번째 결과는 2,B 될 것입니다 : [http://rextester.com/YJKC24018]

지금 LETTER에 의해 순서를 고려하십시오. 레코드 세트가 변경 때문에 오프셋 선택한 그래서 비록 당신은 [http://rextester.com/IBI93830]

CREATE TABLE ExampleTable3 (Id INTEGER, Letter CHAR(1)); 

INSERT INTO ExampleTable3 (Id,Letter) VALUES (1,'A'),(3,'C'),(4,'D'); 

SELECT * 
FROM 
    ExampleTable3 
ORDER BY Letter 
LIMIT 1 OFFSET 1 
; 

INSERT INTO ExampleTable3 (Id,Letter) VALUES (2,'B'); 

SELECT * 
FROM 
    ExampleTable3 
ORDER BY Letter 
LIMIT 1 OFFSET 2 
;  

그래서 여기가 새로운 기록 (2,B) 당신이 (3,C)을받은 마지막 레코드 전에 삽입 한 예입니다 같은 행 또는 새 행을 얻을 수 그 결과로 따라서 OFFSET을 증가 시키더라도 실제로는 동일한 행 (3,C)을 다시 얻습니다.[http://rextester.com/KRVIF54374]

CREATE TABLE ExampleTable4 (Id SERIAL, Letter CHAR(1)); 

INSERT INTO ExampleTable4 (Letter) VALUES ('A'),('C'),('D'); 

SELECT * 
FROM 
    ExampleTable4 
ORDER BY Id 
LIMIT 1 OFFSET 1 
; 

INSERT INTO ExampleTable4 (Letter) VALUES ('B'); 

SELECT * 
FROM 
    ExampleTable4 
ORDER BY Id 
LIMIT 1 OFFSET 1 
;  

DELETE FROM ExampleTable4 WHERE Letter = 'C'; 

SELECT * 
FROM 
    ExampleTable4 
ORDER BY Id 
LIMIT 1 OFFSET 1 
;  

이 예는 ID에 순서는 삭제 이제 결과가 동일한 쿼리로 변경된 테이블에서 발생 한 번을 제외하고, 일관성 유지 수 있음을 보여줍니다. [http://rextester.com/LTN10302]