2016-09-18 3 views
0

lat 및 lng 값을 기반으로 쿼리하려고하지만 값 저장소가 음수 일 때 반환되는 행이 내 쿼리와 일치하지 않습니다. 그러나 내가 긍정적 인 값을 쿼리하면 예상대로 작동합니다. 내 쿼리를 형식화해야하는 특정 방법이 있는지 궁금합니다.Postgres JSONB : 음수로 쿼리

는 여기에 몇 가지 예를 들어 쿼리가 이상한 결과를 증명하기 위해 다음과 같습니다

QUERY 1 
======= 
db_development=# select address from listing where 'address.coords.latitude' < '40'; 

no rows returned. 

QUERY 2 
======= 
db_development=# select address from listing where 'address.coords.latitude' > '40'; 

returned address: 
{ 
    "city":"Heathmere", 
    "state":"VIC", 
    "coords":{ 
    "latitude":-38.19523969999999, 
    "longitude":141.6158994 
    }, 
    "number":"1235", 
    "street":"Princes Highway", 
    "country":"Australia", 
    "zipcode":"3305", 
    "formatted":"Riversleigh, 1235 Princes Hwy, Heathmere VIC 3305, Australia" 
} 

당신은 내가 위도가 40보다 작은 경우 행을 찾기 위해 노력하고 볼 수 있지만 더 행을 반환한다. 그러나 내가 40보다 큰지 확인하면 위도가 -38.19523969999999 인 행이 반환됩니다.

도움을 주시면 감사하겠습니다.

답변

3

당신은 두 가지 문제 또는 동일한 문제가 아마도 두 가지 버전이 더 정확합니다. 쿼리에서 :

select address from listing where 'address.coords.latitude' > '40' 

'address.coords.latitude' 리터럴 문자열입니다의 address JSON에없는 경로; '40'은 문자열 리터럴이며 숫자는 40이 아닙니다. 따라서 WHERE 절은 두 개의 문자열 리터럴을 비교하는 것일 뿐이므로 열에 포함 된 latitude과 숫자 40을 비교하지는 않습니다.

=> select 'address.coords.latitude' < '40' as correct; 
correct 
--------- 
f 
(1 row) 

을하고 두 번째 쿼리의 WHERE 절은 항상 true입니다 : 그 첫 번째 쿼리의 WHERE 절은 항상 false 것을 의미

=> select 'address.coords.latitude' > '40' as confused; 
confused 
---------- 
t 
(1 row) 

당신이 당신의 address JSON 파고하려면

, 특별한 경우의에서

#>>text[]
가 가져 JSON 개체 : 당신은 #>> operator를 사용하려면 텍스트로 D 경로는

그래서 당신은 말할 것 :

address #>> array['coords', 'latitude'] 

가 포함 된 latitude보고; 귀하 또는 귀하의 도구가 #>> 연산자를 좋아하지 않는 경우 jsonb_extract_path_text function을 사용할 수도 있습니다. 그럼 당신은 제대로 작동하고 (숫자) 일반에 그 번호를 비교하는 비교를 얻기 위해 숫자로 그 text 값을 캐스팅해야 할 것 40 :

select address 
from listing 
where (address #>> array['coords', 'latitude'])::numeric < 40 
: 첫 번째 쿼리에 대한 유사

select address 
from listing 
where (address #>> array['coords', 'latitude'])::numeric > 40 

+0

좋은 답변입니다! 고맙습니다 – zlwaterfield

0

예상대로 작동하지 않는 이유는 JSON 텍스트를 텍스트 값과 비교하기 때문입니다.

JSON 값을 적절한 유형 (숫자)으로 변환하고 숫자와 비교해야합니다. 예를 들어

:

select address from listing where ('address.coords.latitude')::numeric < 40; 
+0

그러나''address.coords.latitude ''는 여전히 문자열이며 JSON에 대한 경로는 아닙니다. –