Computer >> 컴퓨터 >  >> 프로그래밍 >> SQL

SQL 서브쿼리 완벽 가이드: 기본 개념부터 SELECT·INSERT·UPDATE·DELETE 실전 활용까지

SQL 서브쿼리(subquery)는 다른 쿼리 내부에 포함된 쿼리를 의미합니다. 주로 SQL 문의 WHERE 절이나 HAVING 절에서 사용되며, 하나의 쿼리 결과를 다른 쿼리의 인자로 지정할 수 있게 해주는 강력한 기능입니다.

SQL 쿼리를 작성하다 보면 다른 쿼리의 실행 결과를 기반으로 조건을 지정해야 하는 경우가 자주 발생합니다. 예를 들어 고객 목록이 있고, 특정 금액 이상의 주문을 한 고객만 조회하고 싶다고 가정해 봅시다. 그런데 주문 정보와 고객 정보는 서로 다른 테이블에 나누어 저장되어 있어 단순한 조회만으로는 원하는 결과를 얻기 어렵습니다.

바로 이럴 때 SQL 서브쿼리가 유용합니다. 서브쿼리는 '중첩 쿼리(nested query)'라고도 불리며, 다른 SQL 쿼리의 WHERE 절 안에 위치한 SELECT 문입니다. 메인 쿼리는 서브쿼리가 반환한 결과를 활용해 최종 결과를 도출합니다.

이 글에서는 몇 가지 실전 예제를 통해 SQL에서 서브쿼리를 사용하는 방법을 자세히 알아보겠습니다.

SQL 서브쿼리 기본 개념

SQL 서브쿼리는 말 그대로 쿼리 안에 포함된 또 다른 쿼리입니다. 다른 쿼리의 결과에 의존하는 쿼리를 실행할 때 사용하며, 두 개의 별도 쿼리를 작성한 뒤 결과를 일일이 복사·붙여넣을 필요 없이 한 번에 처리할 수 있다는 장점이 있습니다. 서브쿼리는 WHERE 절 또는 HAVING 절에 위치합니다.

SQL SELECT 문에서 서브쿼리를 사용하는 기본 문법은 다음과 같습니다:

SELECT name
FROM products
WHERE supplier_id
IN (SELECT id FROM suppliers WHERE local = True);

위 쿼리는 국내(local) 공급업체가 공급하는 모든 제품의 이름을 조회합니다. 여기서는 서브쿼리를 SQL IN 연산자의 입력값으로 사용했습니다. IN 연산자는 products 테이블에서 supplier_id가 서브쿼리 결과에 포함된 모든 레코드를 반환합니다.

서브쿼리는 SELECT 문뿐만 아니라 INSERT, UPDATE, DELETE 문에서도 활용할 수 있습니다.

서브쿼리는 반드시 괄호( ) 안에 작성해야 합니다. 괄호는 서브쿼리의 시작과 끝을 명확하게 구분해 주는 역할을 합니다.

또한 서브쿼리에서 필요한 데이터를 정확히 선택하는 것이 매우 중요합니다. 위 예제에서는 suppliers 테이블에서 id 컬럼을 선택했습니다. 만약 다른 컬럼을 선택했다면 메인 쿼리가 supplier ID에 의존하고 있기 때문에 쿼리가 정상적으로 동작하지 않습니다.

SQL 서브쿼리 예제: SELECT

예를 들어 성적 우수 명단(honor roll)에 오른 학생 목록을 조회하고 싶다면 서브쿼리를 활용할 수 있습니다. 이때 성적 우수 명단 정보는 별도의 테이블에 저장되어 있다고 가정합니다.

다음 예제를 통해 SQL 서브쿼리의 동작 방식을 살펴보겠습니다. 아래 쿼리는 200달러 이상의 주문을 한 적이 있는 모든 고객 목록을 반환합니다:

SELECT * FROM customers
WHERE id IN (SELECT DISTINCT customer_id FROM orders
		WHERE cost > 200);

이 쿼리의 실행 결과는 다음과 같습니다:

nameemailaddressloyalty_planid
Katykaty.l@gmail.comMountain View, CANone4
Johnjohn.p@outlook.comBoston, MANone1

(2 rows)

첫 번째 줄에서 customers 테이블의 모든 컬럼을 선택합니다. 그다음, 고객 ID가 서브쿼리 결과에 포함된 고객만 조회하도록 조건을 지정했습니다. 서브쿼리는 orders 테이블에서 주문 금액(cost)이 200달러를 초과하는 레코드의 고유한 customer_id 값을 추출합니다. 이 조건에 해당하는 고객들이 최종 결과에 포함됩니다.

SQL 서브쿼리: INSERT

이번에는 200달러 이상 구매한 고객의 모든 레코드를 high_value_customers라는 테이블에 삽입해 보겠습니다. SQL 서브쿼리와 INSERT 명령을 함께 사용하면 간단히 처리할 수 있습니다:

INSERT INTO high_value_customers
SELECT * FROM customers
WHERE id IN (SELECT DISTINCT customer_id FROM orders
		WHERE cost > 200);

high_value_customers 테이블을 조회하면 고액 결제 고객 전체를 한 테이블에서 확인할 수 있습니다:

nameemailaddressloyalty_planid
Katykaty.l@gmail.comMountain View, CAGold4
Johnjohn.p@outlook.comBoston, MANone1

(2 rows)

SQL 서브쿼리: UPDATE

서브쿼리는 테이블의 데이터를 수정할 때도 활용할 수 있습니다. 예를 들어 고액 결제를 한 모든 고객의 멤버십 등급(loyalty_plan)을 'High Value'로 변경하고 싶다면 다음과 같은 쿼리를 사용할 수 있습니다:

UPDATE customers
SET loyalty_plan = 'High Value'
WHERE id IN (SELECT DISTINCT customer_id FROM orders
		WHERE cost > 200);

customers 테이블을 다시 조회하면 두 고액 결제 고객의 멤버십 등급이 정상적으로 업데이트된 것을 확인할 수 있습니다:

nameemailaddressloyalty_planid
Katykaty.l@gmail.comMountain View, CAHigh Value4
Johnjohn.p@outlook.comBoston, MAHigh Value1

(2 rows)

SQL 서브쿼리: DELETE

SQL DELETE 문과 함께 서브쿼리를 사용하면 테이블에서 특정 행 또는 여러 행을 한 번에 삭제할 수 있습니다.

앞서 새 테이블로 옮겨둔 고액 결제 고객들의 주문 내역을 삭제하는 명령을 작성해 보겠습니다. 이 작업 역시 서브쿼리에 의존해야 합니다:

DELETE FROM orders
WHERE customer_id IN (SELECT id FROM customers
WHERE loyalty_plan = 'High Value');

실행 결과, 고액 결제 고객들의 모든 주문이 삭제되었습니다. 중첩 서브쿼리가 포함된 쿼리 실행 후 남은 데이터는 다음과 같습니다:

iditem_namecostcustomer_id
5Oak Chair1003

(1 row)

마무리

SQL 서브쿼리는 쿼리 안에 포함된 또 다른 쿼리로, 하나의 쿼리 결과를 다른 쿼리에서 활용할 수 있게 해줍니다. 서브쿼리는 SQL 문의 WHERE 절 또는 HAVING 절에 지정합니다.

서브쿼리를 사용하면 다른 쿼리의 결과에 의존하는 쿼리를 손쉽게 실행할 수 있습니다. 이 가이드에서는 SQL 서버에서 서브쿼리를 작성하는 방법을 살펴보았으며, SELECT, INSERT, UPDATE, DELETE 문에서 서브쿼리를 활용하는 방법도 함께 알아보았습니다.

SQL을 더 깊이 학습하고 싶다면 체계적으로 정리된 SQL 학습 가이드와 검증된 추천 강좌 목록을 참고해 학습 여정을 이어가 보세요. 꾸준한 실습과 예제 학습이 실력 향상의 지름길입니다.