2016-09-08 7 views

답변

1

테이블이 t라고하며 열이 x라고 가정하면 : 그것은 9.3에서 작동해야하므로

SELECT * 
FROM t 
WHERE exists(
    SELECT 1 
    FROM json_array_elements(x#>'{general,tags}') 
    WHERE array_to_json(array[value])->>0='first_tag' 
); 

jsonb 또는 다른 새로운 물건을 사용하지 않습니다. sqlfiddle을 참조하십시오.

아이디어는 함수를 사용하는 것입니다.이 함수는 json 배열을 SQL 테이블로 변환합니다. 이 테이블에는 json 유형의 단일 열이 있습니다.

이 경우 하위 태그에 json_array_elements을 사용하여 모든 태그 목록을 반복합니다. 하나의 합병증은 value (여기서는 태그를 나타냄)이 json이기 때문에 텍스트로 변환해야합니다. 불행하게도 postgresql에는이를 직접 수행하는 함수가 없으므로이를 단일 요소 배열로 변환 한 다음 해당 단일 요소를 텍스트로 추출해야합니다. 그런 다음 텍스트를 우리가 찾고있는 태그와 비교할 수 있습니다 (위의 예에서 first_tag). 이 열의 결과는 중요하지 않으며 비어 있는지 여부에만 관심이 있습니다.

+0

나는 당신의 예에서 내부 쿼리를 실행하면, 나는 모든 기록에서 태그의 목록을 가져옵니다. 그러나 전체 쿼리를 실행하면 0 줄을 얻습니다. – BanzaiTokyo

+0

@BanzaiTokyo 문자열 테스트를 조정하면 작동 할 것입니다. – redneb

+0

나는 그것이 어떻게 작동하는지 전혀 모른다. 그러나 그것은한다!! 정말 고맙습니다! Postgres 9.3에서 "contains"와 같은 용어에 대해 json을 질의하는 것에 대해 더 많이 읽을 수있는 링크를 공유 할 수 있다면 고맙겠습니다. 왜냐하면 [documentation] (https://www.postgresql.org/docs/9.3/static/functions-json.html)은 그다지 설명하지 않기 때문입니다. – BanzaiTokyo

0

당신은 사용할 수 있습니다

CREATE OR REPLACE FUNCTION fn_json_array_contains(a_json json, a_e anyelement) 
RETURNS BOOLEAN AS $BODY$ 
BEGIN 
    RETURN to_json(a_e)::TEXT IN (SELECT value::TEXT FROM json_array_elements(a_json) e); 
END; 
$BODY$ LANGUAGE plpgsql IMMUTABLE 
; 

SELECT * FROM t WHERE fn_json_array_contains(x#>'{general,tags}', 'first_tag');