2014-12-05 1 views
9

Oracle 11gR2 Expression Edition 사용. 내 데이터는 우리가 열 값의 특정 범위 내에없는 경우 기록을 찾기 위해 노력하고있다
문자열 비교를위한 Oracle과 다른 결과가 같지 않음 <= and > =

ordertype 
--------- 
ZOCO 
ZOSA 
ZOST 

를 다음과 같습니다.

내가 <하여 쿼리를 실행하면

= 및> = 운영자 : SELECT * FROM table where ordertype <= 'ZAAA' OR ordertype >= 'ZZZZ'; 는 내가 0 결과를 얻을 수 있습니다. 이것은 올바른 대답입니다. I 사이에 사용하지 않을 경우

그러나 : SELECT * FROM table where ordertype NOT BETWEEN 'ZAAA' AND 'ZZZZ'; , 그것은 여러 히트 곡을 제공합니다.

제 생각에는 두 구문 모두 동일한 결과를 주어야하지만 이해하지 못하는 것입니다. 내가 뭘 놓치고 있니? 이유 기존의 많은 코드는 이미이 구문을 가지고 있으며 이유를 이해하지 않고 변경하지 않기 때문에 NOT BETWEEN을 사용하고 싶습니다.

감사합니다.


게시자 여러분 께 감사드립니다. 쿼리를 다시 실행하고 첫 번째 쿼리에서 "OR"을 수정 한 후 결과가 동일합니다. 나는 오라클 문자 정렬이 예상대로 인식하지 못하는 이유에 대해 여전히 의문이 있지만 NOT BETWEEN과 <의 차이점에 대한 나의 질문은 거짓 경보입니다. 혼란에 사과드립니다.

+0

위의 질문에 오타가 생겼습니다. 내가 쓰려고했던 첫 번째 쿼리는 ordertype <= 'ZAAA'또는 ordertype> = 'ZZZZ'입니다. – user3208146

+0

게시 한 모든 사람들에게 감사드립니다. 쿼리를 다시 실행하고 첫 번째 쿼리에서 "OR"을 수정 한 후 결과가 동일합니다. 나는 오라클 문자 정렬이 예상대로 인식하지 못하는 이유에 대해 여전히 의문을 가지고 있지만 NOT BETWEEN과 <> 사이의 차이점에 대한 나의 질문은 거짓 경보입니다. – user3208146

+1

이제'및'을'또는'로 변경 한 후에 두 문장 모두 실제로 동일한 레코드를 반환한다고 확신합니다. http://sqlfiddle.com/#!4/d8ac4/1을 실행하여 반환되는 레코드를 알려주십시오. 또한'select dump (ordertype) from table에서 ordertype이 'ZAAA'와 'ZZZZ'사이에 있지 않은 것을 선택하고 결과를 게시하십시오. –

답변

10
SELECT * FROM table where ordertype <= 'ZAAA' AND ordertype >= 'ZZZZ'; 

없음 문자열은 < = 'ZAAA'> = 'ZZZZ'을 수 없다. 당신은 대신 분리를 사용해야합니다 :

BTW
SELECT * FROM table where ordertype < 'ZAAA' OR ordertype > 'ZZZZ'; 

, NOT BETWEEN이 공통의 함정이다


독점, BETWEEN을 포함하는 것을 주어진.

not (A and B)(not A) or (not B)

그 결과는 매우 일관된 것을 자신을 설득하기 위해 간단한 라이브 예를 실험 자유롭게과 동일합니다 : 당신은 De Morgan's Laws가 기억해야 http://sqlfiddle.com/#!4/d41d8/38326


즉, 유일한 방법은) ZOCO 같은 문자열을 ZAAAZZZZ 사이에있는 하지이 될 것입니다 :

  • 그냥 Z 뒤에 몇 가지 숨겨진 문자를 가진 (즉,: 'Z'||CHR(0)||'OCO')
  • 또는 주어진 범위 이외의 배열 순서와, 이러한Z 같은 - 비슷한 실제로 다른 문자로 간주되는 로케일을 사용. 그러한 로케일이 존재하는지는 잘 모르겠지만, 예를 들어 Welch에서는 LL을 일반 문자 L 다음에 정렬해야하는 단일 문자로 간주합니다. http://en.wikipedia.org/wiki/Alphabetical_order#Language-specific_conventions
  • 또는이 데이터에 homogplyphs 같은 0, 또는 О 대신 O을 가진 참조하십시오.
+4

(페이스 플레이트의 먼 소리) 30 년 동안 컴퓨터 과학 분야의 학위를 받았지만 아직까지는 발견 할 수 없었습니다. :-) 나는 분명한 징후로 소진되고있다. +1 잘 설명 답변. – nop77svk

+0

안녕 Sylvain, 지적을 주셔서 감사합니다 - 내 첫 번째 쿼리를 수정했습니다 - 어디 ordertype < 'ZAAA'또는 ordertype> 'ZZZZ'쿼리하려면 노력하고있어. 그런 말로 DeMorgan의 법에 대한 설명을 이해하지 못했습니다. 위의 귀하의 의견에 근거한 'ZAAA'와 'ZZZZ'는 (ordetype> 'ZAAA'가 아님) 또는 (ordertype < 'ZZZZ'가 아님)으로 번역됩니다. ZOCO는 그 (false) 또는 (false)를 제공 할 것이므로 - 그 쿼리로부터 ZOCO를 리턴해서는 안된다. – user3208146

+0

@ user3208146 죄송합니다. 그 이상은 말할 수 없습니다. 'ZOCO'와 'ZAAA'및 'ZZZZ'가 _false_ 인 경우 내 마음에 떠오를 수있는 유일한 설명은 내 대답의 두 번째 부분.일부 숨겨진 문자 또는 'ZO'자모를 별도의 문자로 간주하는 데이터 정렬 - 또는 동형 문자. –

2

두 진술이 모두 동일하다는 것을 알고 있습니다. NOT BETWEEN은 생각하는 방식으로 평가되지 않습니다. 단순히 매개 변수에 대해 BETWEEN의 평가를 벗어나는 결과를 반환합니다. 당신이 간의 에 대한 Oracle 설명서를 선택하면

, 그것은 말한다 -

The value of 

expr1 NOT BETWEEN expr2 AND expr3 
is the value of the expression 

NOT (expr1 BETWEEN expr2 AND expr3) 
+1

아니요, NOT BETWEEN은 모든 레코드를 반환하지 않아야합니다. 'ZAAA'와 'ZZZZ'사이의 레코드 (예 :'ZBCD')는 두 문장 모두에 반환되지 않습니다. –

+1

그래, 네가 맞아! – Incognito

+0

감사합니다. 따라서 ZOCO는 ZOCA와 ZZZZ의 오라클 문자 정렬을 기반으로하므로 ZOCO를 반환하면 안됩니다. – user3208146

2

는 값 사이가 아니라면, 그것은 < OR>,하지 및이어야한다.

2

첫 번째 쿼리에서 동시에 'ZAAA'보다 작고 보다 큰보다 작은 레코드를 요청합니다. 물론 두 가지 요구 사항을 모두 채우는 값이 없기 때문에 0 레코드가 반환됩니다. 두 번째 쿼리에서

, 당신이 그 레코드를 요청 중 하나 미만 'ZAAA'또는 이상 'ZZZZ' (즉되지 않은 경계 [not between...] 사이). 그러한 기록이 존재할 가능성이 있으며, 귀하의 선택 진술서가 증명하는 바와 같이 실제로 진술서에 의해 반환되는 그러한 기록들이 있습니다.

+0

질문을 잘못 작성했습니다. 첫 번째 쿼리는 ordertype < 'ZAAA'또는 ordertype> 'ZZZZ'이어야하며 두 번째 ordertype은 'ZAAA'및 'ZZZZ'가 아닙니다. – user3208146

관련 문제