| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- db
- index
- PostgreSQL
- aws
- SubQuery
- DDL
- 보안 그룹
- redis
- 탄력적 ip
- 정규화
- NoSQL
- Join
- EC2
- sub-query
- Github Actions
- SQLite
- 정보처리기사
- dml
- CTE
- MySQL
- DevOps
- VPC
- Transaction
- SQL
- ASW
- databse
- springboot
- database
- mongoDB
- 정처기
- Today
- Total
sellen
SQL에서 JSON 다루기 본문

💡 이 내용 이후로 모든 SQL 관련 내용은 NomadCoder 강의를 듣고 정리한 글입니다.
아래의 링크에 SQL 학습에 필요한 데이터가 존재합니다.
https://nomadcoders.co/sql-masterclass
MySQL과 PostgreSQL에서는 JSON 데이터를 조회할 수 있다.
JSON 타입 컬럼을 가진 테이블 생성
CREATE TABLE users (
user_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
profile JSONB
);
| 구분 | 설명 |
| JSON |
|
| JSONB |
|
JSON 타입 컬럼에 데이터 입력
INSERT INTO users (profile)
VALUES
('{"name": "Nico", "age": 30, "city": "Berlin"}'),
(json_build_object(
'name', 'Lynn',
'age', 25,
'city', 'Korea',
'hobbies', json_build_array('music', 'movies')
));
- json 데이터를 ‘ ‘ 로 감싸주고 key와 문자열 value는 “ “ 로 감싸야한다.
- ‘ ‘, “ “, { } 등을 실수로 빼먹을 경우 INSERT가 되지 않는다.
- 이를 방지하기 위해 json_build_object( ), json_build_array( )를 사용하면 편하다.
JSON 데이터 조회
{column_name} -> {json_key} 또는 {column_name} ->> {json_key}
SELECT
profile ->> 'name' AS name, -- -> 만 사용할 경우 " "로 감싸서 출력된다.
profile -> 'age' AS age,
profile -> 'hobbies' AS hobbies,
profile -> 'hobbies' -> 0 AS first_hobby -- 리스트의 첫번째 값을 출력한다.
FROM users;
해당 방법으로 json에서 원하는 key만 조회를 할 수 있다.
해당 key가 존재하지 않을 경우 null로 출력된다.
JSON Update
데이터를 추가로 입력할 경우 {column_name} = {column_name} || {key : value}를 사용한다.
UPDATE users
SET profile = profile || '{"email": "123@wow.com"}' -- 기존 데이터에 추가한다.
WHERE user_id = 1;
UPDATE users
SET profile = '{"email": "123@wow.com"}' -- 기존 데이터가 사라지고 email 데이터만 남는다.
WHERE user_id = 1;
JSON Delete
JSON Key 제거
UPDATE users
SET profile = profile - 'email' -- key 가 email인 데이터를 제거한다.
WHERE user_id = 1;
JSON Key의 리스트 원소 제거
jsonb_set( {column_name}, {key}, {query} )
UPDATE users
SET profile = profile || jsonb_set(
profile,
'{hobbies}',
-- hobbies 리스트에서 dancing 제거
profile -> 'hobbies' - 'dancing'
);
JSON 관련 함수 & 연산자
https://www.postgresql.org/docs/9.5/functions-json.html
JSON Functions and Operators
Table 9-40 shows the operators that are available for use with the two JSON data types (see Section 8.14). Table 9-40. json and jsonb Operators Operator Right Operand Type Description Example Example Result -> int Get JSON array element (indexed from zero,
www.postgresql.org
JSON 연산자
| 함수 | 기능 | 예시 |
| -> | 객체의 key에 접근 | profile -> 'name' |
| ->> | 객체의 key 데이터를 문자열로 변환 | profile ->> 'name' |
| ? | 해당 배열 또는 객체에 데이터가 존재하는지 확인 | profile ? 'hobbies' profile -> 'hobbies' ? 'music' |
| | | 여러 데이터 중 하나 이상 존재할 경우 | profile -> 'hobbies' ?| array[’music’, ‘reading’] profile ?| array[’age’, ‘city’] |
| & | 여러 데이터 중 전부 존재할 경우 | profile -> 'hobbies' ?& array[’music’, ‘reading’] profile ?& array[’age’, ‘city’] |
| || | 기존 json 데이터에 추가로 데이터 입력 | profile = profile || '{"email": "123@wow.com"}' |
| - | key나 리스트의 원소를 기준으로 데이터 제거 | profile = profile - 'email' |
특정 Key가 존재하는지 여부
SELECT
profile ->> 'name' AS name,
profile -> 'age' AS age,
profile -> 'hobbies' AS hobbies
FROM users
WHERE profile ? 'hobbies';
key에 hobbies가 존재하는 데이터만 출력한다.
Key의 리스트에 특정 데이터가 있는지
SELECT
profile ->> 'name' AS name,
profile -> 'age' AS age,
profile -> 'hobbies' AS hobbies
FROM users
WHERE profile -> 'hobbies' ? 'music';
key의 hobbies 리스트에 music이 존재하는지 조회한다.
Key 리스트의 길이 출력
column 타입이 JSONB일 경우 jsonb_ 함수를 사용해야한다.
SELECT
jsonb_array_length(profile -> 'hobbies') AS total_hobbies -- hobbies 리스트의 길이
FROM users;
Key에 특정 데이터가 존재하는지 조회
SELECT
profile ->> 'name' AS name
FROM users
-- -> 를 사용하면 문자열로 출력되지 않으므로 에러가 발생
WHERE profile ->> 'name' = 'Nico';
숫자 비교
SELECT
profile ->> 'name' AS name
FROM users
-- ( ) :: {type}을 사용하여 형변환을 해야한다.
WHERE (profile ->> 'age') :: integer < 30;
JSON 함수
json_set, jsonb_set
UPDATE users
SET profile = profile || jsonb_set(
profile,
'{hobbies}',
profile -> 'hobbies' - 'dancing'
);
profile 컬럼의 hobbies Key의 값을 hobbies 리스트에서 dancing을 뺀 리스트로 저장
SET profile = profile || jsonb_set(
profile, '{hobbies}',
profile -> 'hobbies' || jsonb_build_array('cooking')
)
WHERE user_id = 1;
profile 컬럼의 hobbies Key의 값을 hobbies 리스트에서 cooking이 추가된 리스트로 저장
연습 문제
hobbies를 기준으로 해당 취미를 가지고 있는 사람이 몇 명인지 출력
SELECT
jsonb_array_elements_text(profile -> 'hobbies'),
count(*)
FROM users
GROUP BY jsonb_array_elements_text(profile -> 'hobbies');
'DataBase > 관계형 DB' 카테고리의 다른 글
| PostgreSQL Extensions (2) | 2025.07.21 |
|---|---|
| DCL (0) | 2025.07.21 |
| Transaction (1) | 2025.07.21 |
| Function & Procedures (5) | 2025.07.21 |
| 정규화 - PostgreSQL (1) | 2025.07.20 |