본문 바로가기
DB/MySQL

[MySQL] 서브쿼리

by 애기 개발자 2022. 10. 3.
반응형

DB를 다루다 보면 2개 이상의 테이블을 합쳐서 사용하게 되는데

 

이때 종종 사용하게 되는 방법이다.

 

서브 쿼리가 사용 가능한 곳

  1. SELECT 절
  2. FROM 절
  3. WHERE 절
  4. HAVING 
  5. ORDER BY  
  6. INSERT 문의 VALUES 
  7. UPDATE 문의 SET  

주로 위의 7가지 위치에서 사용된다.

 

예시

User_Info

UserID UserName UserDeptCode RoleName
cskim 김철수 10001 팀장
yhpark 박영희 10001 부장
gdhong 홍길동 10002 과장
kanu 공유 10002 대리
zin9 노진구 10002 대리

 

Org_Info

DeptCode DeptName
10001 경영팀
10002 개발팀
10003 QA
10004 전략실

 

1. SELECT 절

Scala 서브 쿼리

select 절에 들어가야 하기 때문에 하나의 결과값만을 리턴하도록 작성되어야 한다.

 

SELECT UserID, (SELECT DeptName FROM Org_Info WHERE DeptName = '경영팀') AS DeptName 
FROM User_Info WHERE UserName = '김철수';

만약 쿼리를 잘못 짤 경우

SELECT UserID, (SELECT DeptName FROM Org_Info WHERE DeptName = '경영팀') AS DeptName FROM User_Info;

이러한 결과나

 

혹은 서브 쿼리가 두 개 이상의 값을 리턴하면

 

SELECT UserID, (SELECT DeptName FROM Org_Info) AS DeptName FROM User_Info WHERE UserName = '김철수';

Subquery returns more than 1 row

에러를 보게 된다

 

2. FROM 절

Inline 뷰라고도 불린다.

FROM 절은 그 위치의 특성상 테이블 명이 와야 한다.

 

인라인 뷰는 마치 join을 쓴 것과 같다.

 

SELECT t1.UserID, t2.DeptCode FROM User_Info t1, (SELECT DeptCode FROM Org_Info) t2 
WHERE t1.UserDeptCode = t2.DeptCode;

 

3. WHERE 절

아마 가장 흔하게 쓰는 방법이 아닐까 싶다.

 

where 안에서 서브 쿼리를 생성하는 것으로 일반적으로 where 절 안에서 쓰듯이 어렵지 않게 사용하면 된다.

 

SELECT * FROM User_Info WHERE UserDeptCode = (SELECT DeptCode FROM Org_Info WHERE DeptName = "경영팀");

 

4. 그 외

HAVING 은 GROUP BY와 함께 묶여서 GROUP BY에 좀 더 조건을 주기 위해 사용하는 기능을 한다.

 

HAVING 은 위의 WHERE 절처럼 HAVING 안에서 단순하게 사용하면 된다.

 

SELECT UserDeptCode FROM User_Info 
GROUP BY UserDeptCode HAVING UserDeptCode = (SELECT DeptCode FROM Org_Info WHERE DeptCode = '10002');

나머지 ORDER BY 절이나, INSERT문의 VALUES, UPDATE의 SET 내부에서도 위와 동일하게 사용하면 된다.

 

INSERT 문의 VALUES에 사용할 때는 추가하고자 하는 값을 넣어주면 된다.

 

INSERT INTO t1 (a, b, c) VALUES( (SELECT a FROM t2), (SELECT b FROM t2), (SELECT c FROM t3) );

 

주의할 점

서브 쿼리를 사용하다 보면 맞는 문법을 사용했지만

 

Subquery returns more than 1 row

 

에러를 보는 경우가 종종 있다.

 

SELECT * FROM Org_Info WHERE DeptCode = (SELECT UserDeptCode FROM User_Info WHERE RoleName ="대리");

위의 쿼리를 실행시키면

Subquery returns more than 1 row 에러가 발생하는데

 

이는 User_Info 테이블에 '대리' 값이 2개라서 그렇다. 이럴 땐 반드시 다중 행 비교 연산자가 필요하다.

 

다중 행 비교 연산자로는 IN, ALL, ANY, EXISTS  4 종류가 있다.

 

SELECT * FROM Org_Info WHERE DeptCode IN (SELECT UserDeptCode FROM User_Info WHERE RoleName ="대리");

IN - 서브 쿼리 출력 결과와 하나라도 일치하면 출력

ALL - 서브 쿼리에 검색된 조건을 모두 만족하면 출력

ANY - 서브쿼리에 검색된 조건 중 하나 이상 만족하면 출력

EXISTS - 서브 쿼리의 결과에 만족하는 값이 존재하는지 여부

 

반응형

댓글