-
[SQLite] 중첩 질의 (Nested query)Software/SQLite 2017. 11. 27. 00:18반응형
데이터 중복성과 종속성을 최소화 하기 위해 데이터를 여러 테이블에에 분산 저장하는 것은 관계형 데이터베이스 설계에 있어 매우 중요한 부분이다. 그러나 분산된 데이터를 조회하기 위해 여러 테이블에 Select문을 수행해야 하는 단점도 발생하게 된다. 이러한 단점을 극복하기 위한 방법으로 "중첩 질의" 혹은 "조인 연산"이 있다. 그 중 중첩 질의는(Nested query)는 SQL 문 안에 또 다른 SQL 문을 포함하고 있는 구조이다.
조건절의 중첩 질의
먼저 carBrand 테이블에서 brandName이 "Kia"인 레코드의 brand_id를 조회해 보자
sqlite> SELECT brand_id FROM carBrand WHERE brandName='Kia';
brand_id
2
그리고 cars 테이블에서 brand_id가 2인 값의 레코드의 name과 price를 조회해 보자.
sqlite> SELECT name, price FROM cars WHERE brand_id = 2;
name|price
K5 |1500000
K3 |1200000
K7 |2200000
우리는 여기서 두번째 질의문의 조건 절인 WHERE brand_id=2의 2 값이 첫번째 carBrand테이블의 질의 결과임을 알 수 있다. 그러므로 우리는 두 번째 질의문의 조건절에서 2라는 값 대신 첫 번째 질의문으로 대체하도록 하여 질의를 한 번만 수행하도록 할 수 있다. 아래의 질의문이 앞서 질의한 두 질의문을 하나로 합친 것이다.
sqlite> SELECT name, price FROM cars
WHERE brand_id = (SELECT brand_id
FROM carBrand
WHERE brandName = 'Kia');
name|price
K5 |1500000
K3 |1200000
K7 |2200000
중첩 질의의 수행 순서: 가장 안쪽 -> 바깥쪽
그렇다면 IN 연산자와 같이 복수의 조건 인자를 사용해야 하는 경우에는 어떻게 해야 할까?
예를들어 brandName이 "Kia"와 "Hyundai"인 레코드를 조회하는 경우를 생각해 보자
먼저 앞서 보여준 거와 같이 carBrand테이블에서 IN연산자를 사용하여 brandName이 "Kia", "Hyundai"인 레코드의 brand_id를 조회해 보도록 하자.
sqlite> SELECT brand_id FROM carBrand WHERE brandName IN ("Kia", "Hyundai");
brand_id
1
2
위에서 얻어진 brand_id 결과 값을 이용하여 cars 테이블에서 해당 brand_id 값을 가지는 레코드의 name과 price를 조회해 보자.
sqlite> SELECT name, price FROM cars WHERE brand_id IN (1, 2);
name|price
Sonata|1500000
K5|1500000
K3|1200000
K7|2200000
정상적으로 Hyundai와 Kia의 자동차들의 이름과 가격이 조회되었다.
이제 이를 중첩 질의를 통해서 질의가 한 번만 수행되도록 해보자. 방법은 앞서 한 방법과 동일하다. 두 번째 질의의 조건절 부분에 첫 번째 질의문을 넣으면 된다.
sqlite> SELECT name, price FROM cars
...> WHERE brand_id IN ( SELECT brand_id FROM carBrand
...> WHERE brandName IN ("Kia", "Hyundai"));
name|price
Sonata|1500000
K5|1500000
K3|1200000
K7|2200000
검색 컬럼의 중첩 질의
이번에는 집계 함수를 같이 사용하여 SELECT 문의 검색 컬럼으로 중첩 질의를 사용하는 방법에 대해서 알아 보도록 하자.
자동차 브랜드 별로 출시 한 자동차의 종류의 수를 보여주기 위해서 우리는 먼저 SELEC 문에 brandName과 해당 brand의 brand_id를 가지는 자동차의 수를 가져오도록 하면 된다.
sqlite> SELECT brandName, ( SELECT COUNT(*) FROM cars
WHERE cars.brand_id = carBrand.brand_id) AS count FROM carBrand;
brandName|count
Hyundai|1
Kia|3
BMW|0
Benz|0
Audi|0
brand_id와 같은 다른 table에 동일한 column명이 존재한다면 테이블 이름을 해당 column명 앞에 "."와 함께 명시해 주어야 한다.
반응형'Software > SQLite' 카테고리의 다른 글
[SQLite] 자체 조인 (SELF JOIN) (0) 2018.01.14 [SQLite] 내부 조인(Inner Join) (0) 2018.01.13 [SQLite] 외래키 (Foreign Key) (0) 2017.10.15 [SQLite] 기본키 (Primary Key) (0) 2017.09.16 [SQLite] 관계형 데이터베이스 (0) 2017.09.02 댓글