데이터베이스

SQL (9) - SUBQUERY

monstro 2025. 2. 12. 12:18
728x90
반응형

이번 포스트에서는 쿼리문에 사용가능한 SUBQUERY 또는 하위 쿼리에 대해 알아보겠습니다.

하위 쿼리를 사용하게 되면 쿼리문의 로직을 유연하게 만들 수 있는 장점이 있습니다.

 

1) 일반 쿼리 VS 하위 쿼리

-- 연봉이 높은 선수의 정보를 가져오고,
SELECT TOP 1 *
FROM salaries
ORDER BY salary DESC;

-- 출력된 정보에서 선수 ID를 통해 데이터를 골라옴
SELECT *
FROM players
WHERE playerID = 'rodrial01'

 

위의 쿼리문은 두 개의 단계를 거쳐 진행됩니다.

우선, 연봉이 제일 높은 선수의 정보를 가져오고 가져온 선수의 ID를 통해 데이터를 가져옵니다.

실행 결과는 다음과 같습니다.

 

이때, 하위 쿼리를 사용하게 되면 위의 2가지 절차를 하나의 절차로 만들 수 있습니다.

SELECT *
FROM players
WHERE playerID = (SELECT TOP 1 playerID FROM salaries ORDER BY salary DESC);

 

실행결과는 위와 동일합니다.

 

 

2) 다중 행에 하위 쿼리 적용

SELECT *
FROM players
WHERE playerID IN (SELECT TOP 20 playerID FROM salaries ORDER BY salary DESC);

 

이번에는 여러개의 행에 하위 쿼리를 적용해보겠습니다.

salary로 내림차순 정렬한 후 상위 20개의 playerID를 가진 데이터를 가져와보겠습니다

실행 결과는 다음과 같습니다.

 

분명히, 20개의 데이터를 가져오도록 하였지만 9개의 데이터만 가져온 것을 확인할 수 있습니다.

그 이유는 IN 연산자를 사용하게 되면 중복되는 데이터는 무시하기 때문입니다.

따라서 위와 같은 결과가 나오게 됩니다.

 

 

3) WHERE문이 아닌 하위 쿼리의 사용

3 - 1) SELECT 문

SELECT (SELECT COUNT(*) FROM players) AS playerCount, (SELECT COUNT(*) FROM batting) AS battingCount;

 

위 쿼리의 경우, 하위 쿼리를 WHERE문이 아닌 SELECT문에 사용하였습니다.

players 테이블에서 선수들의 총인원수를 playerCountr로,

batting 테이블에서 총 타수를 battingCount로 가져오도록 하였습니다.

실행 결과는 다음과 같습니다.

 

 

3 - 2) INSERT 문

-- VALUES를 사용하여 추가할 데이터를 지정
INSERT INTO salaries
VALUES (2024, 'KOR', 'NL', 'Kim', (SELECT MAX(salary) FROM salaries));

-- SELECT를 사용하여 추가할 데이터를 지정
INSERT INTO salaries
SELECT 2024, 'KOR', 'NL', 'Park', (SELECT MAX(salary) FROM salaries);

 

테이블에 데이터를 추가하는 INSERT 문에도 하위 쿼리를 사용할 수 있습니다.

salaries 테이블에 총 2개의 데이터를 추가합니다.

이때, 추가되는 데이터의 salary 속성의 값은 최대치로 설정하여 추가하게 됩니다.

실행 결과는 다음과 같습니다.

 

 

3 - 3) 연결 관계 하위 쿼리

-- 일반적인 방법으로 포스트 시즌 타격에 참여한 선수들의 목록 가져오기
SELECT *
FROM players
WHERE playerID IN (SELECT playerID FROM battingpost);

 

위의 쿼리는 players 테이블의 playerID를 battingpost 테이블의 PlayerID에 있는지 판단하여

데이터를 가져오는 쿼리입니다.

실행 결과는 다음과 같습니다.

 

 

위의 경우처럼 사용할 수 있지만, 하위 쿼리의 문법EXISTS / NOT EXISTS를 사용하여

데이터가 존재하는지를 판단할 수도 있습니다.

SELECT * 
FROM players
WHERE EXISTS (SELECT playerID FROM battingpost WHERE battingpost.playerID = players.playerID);

 

위 쿼리의 실행 결과는 다음과 같습니다.

 

 

Ctrl + L을 눌러 쿼리의 동작 비용을 비교해봐도 큰 차이가 없음을 알 수 있습니다.

하위 쿼리를 사용하지 않은 경우

 

하위 쿼리를 사용한 경우

 

728x90
반응형

'데이터베이스' 카테고리의 다른 글

SQL (11) - 정규화  (0) 2025.02.12
SQL (10) - DDL  (0) 2025.02.12
SQL (8) - 데이터 조작어(DML)  (0) 2025.02.11
SQL (7) - GROUP BY  (0) 2025.02.11
SQL (6) - 집계 함수  (0) 2025.02.10