MySQL 쿼리 결과를 하나의 문자열, 또는 JSON으로 가져오기
쿼리 결과 컬럼값들을
배열이나 문자열, CSV 형태, 또는 JSON으로 반환해야 할 경우
보통은 결과값을 루프를 돌며 재가공 처리를 해야 합니다.
언어, 또는 프레임워크에 따라서는 쿼리 결과를 자동으로 JSON 이나 문자열 등의 형태로 생성해주는 메써드를 제공해주기도 하기 때문에
이런 기능이 지원될 경우 이 기능을 사용하는 것을 추천합니다.
또는 루프를 돌아 쿼리 결과를 재가공 하는 메써드나 함수를 아얘 만들어 재사용 해도 되기 때문에
초기 작업을 제외하면 그닥 번거로울 일은 없겠지만
결과값을 얻는데 서버의 리소스와 더 많은 런타임 시간을 요구하게 됩니다.
MySQL 에는 이런 경우를 위해 GROUP_CONCAT() 함수가 지원되며,
이 함수를 이용하면 결과 컬럾값들을 구분 기호로 구분된 하나의 문자열로 반환할 수 있습니다.
루프를 돌아 재가공을 하는 것보다는 DB내에서 처리되기 때문에 런타임 시간이 더 짧고 효율적입니다.
예를들어
아래와 같은 결과를 가져오는 쿼리가 있다면
select email from member where emailyn = 'Y' and email <> '';
회원들에게 뉴스레터를 보내기 위해 회원정보 테이블에서 이메일 주소를 콤마로 구분된 하나의 문자열로 얻고 싶다면
select GROUP_CONCAT(email SEPARATOR ',') as emails from member where emailyn = 'Y' and email <> '';
이렇게 작성하면 됩니다.
where 절은 이메일 주소 필드가 비어있지 않고 뉴스레터 발송을 허용한 회원 이메일만 가져오는 조건 체크를 하는 것이므로 제외하고
GROUP_CONCAT(email SEPARATOR ',')
이 함수이 이메일 주소를 하나의 문자열로 이메일 필드들을 묶어주는 함수입니다.
group_concat() 함수를 이용하면 emails 필드명을 가진 한개의 레코드만을 리턴합니다.
리턴된 결과는 별도의 가공없이 바로 클라리언트로 리턴할 수 있습니다.
또는 JSON 문자열로 쿼리 결과를 얻고 싶은 경우
위의 쿼리를 응용해서 중첩 쿼리로 JSON 문자열을 생성할 수 있습니다.
SELECT CONCAT('[', jsonarray, ']') AS emails FROM(
SELECT GROUP_CONCAT('{', jsonitem, '}' SEPARATOR ',') AS jsonarray FROM ( SELECT CONCAT ( '"email":' , '"', email , '"' ) AS jsonitem FROM member r where emailyn = 'Y' and email <> '' ) AS singlejson ) AS alljson;
최종 쿼리문을 이렇습니다.
다소 복잡해 보이지만 안에서부터 select 쿼리를 3개를 중첩해서 올린 것이고
안에서부터 JSON 아이템 1개, 그 위에서 JSON 어레이를 쉼표로 연결해 붙이고, 제일 바깥에서 최외각 JSON "[]" 기호를 붙여서 최종적으로는
이런 단일 문자열로 된 JSON 문자열 레코드 한개를 리턴하게 됩니다.
잘 이해가 안될 경우 안에서 부터 select 쿼리문을 단계별로 올라오면서 실행해 보면 바로 이해가 될겁니다.