이번 포스팅은 MySQL에서 서브쿼리(SubQuery)를 쓰는 방법 입니다.
서브쿼리(SubQuery)란, 하나의 SQL문 안에 포함되어 있는 또 다른 SQL문을 말합니다.
서브쿼리는 메인 쿼리가 서브 쿼리를 포함하는 종속적인관계 입니다.
조인(Join)은 조인에 참여하는 모든 테이블이 대등한 관계에 있기 때문에 조인에 참여하는 모든 테이블의 칼럼을 어느 위치에서라도 자유롭게 사용할 수 있습니다.
그러나 서브쿼리는 메인쿼리의 칼럼을 모두 사용할 수 있지만, 메인쿼리는 서브쿼리의 칼럼을 사용할 수 없습니다.
조인은 집합에 비유하면 곱의 관계입니다. 따라서 1:1 관계의 테이블을 조인하면 1*1=1 레벨의 집합이 생성되고, 1:M 관계의 테이블을 조인하면 M(1*M) 레벨의 집합이 생성됩니다. 그리고 M:N관계의 테이블을 조인하면 MN(M*N) 레벨의 집합이 됩니다.
그러나, 서브쿼리는 서브쿼리 레벨과는 상관없이 항상 메인쿼리 레벨로 결과 집합이 생성됩니다.
서브쿼리를 사용할 때 주의할 점
1. 서브쿼리를 괄호로 감싸서 사용
2. 서브쿼리는 단일 행 또는 복수 행 비교 연산자와 함께 사용 가능
3. 서브쿼리에서는 ORDER BY를 사용하지 못한다.
서브쿼리의 사용이 가능한 곳
- SELECT
- FROM
- WHERE
- HAVING
- ORDER BY
- INSERT문의 VALUES
- UPDATE문의 SET
서브쿼리의 종류
① 단일행 서브쿼리(Single Row Subquery)SELECT * FROM Player WHERE Team_ID = ( SELECT Team_ID FROM Player WHERE Player_name = "player1" ) ORDER BY Team_name;
② 다중행 서브쿼리(Multiple Row Subquery)
SELECT * FROM Team WHERE Team_ID IN ( SELECT Team_ID FROM Player WHERE Player_name = "player1" ) ORDER BY Team_name;
③ 다중컬럼 서브쿼리(Multi Column Subquery)
SELECT * FROM Player WHERE (Team_ID, Height) IN ( SELECT Team_ID, MIN(Height) FROM Player GROUP BY Team_ID ) ORDER BY Team_ID, Player_name;
위치에 따라 사용되는 서브쿼리
① SELECT 절에서 사용되는 서브쿼리
SELECT Player_name, Height, ( SELECT AVG(Height) FROM Player p WHERE p.Team_ID = x.Team_ID) as AVG_Height FROM Player x
② FROM 절에서 사용되는 서브쿼리
FROM 절에서 사용되는 서브쿼리를 인라인 뷰(Inline View)라고 한다. FROM 절에는 테이블 명이 오도록 되어 있다. 그런데 서브쿼리가 FROM절에 사용되면 뷰(View)처럼 결과가 동적으로 생성된 테이블로 사용할 수 있다.
또한, 인라인 뷰로 동적으로 생성된 테이블이여서 인라인 뷰의 칼럼은 자유롭게 참조가 가능하다.
SELECT t.Team_name, p.Player_name, p.Height FROM Player t, ( SELECT Team_ID, Player_name, Back_no FROM Player WHERE Position = 'MF') p WHERE p.Team_ID = t.Team_ID;
③ WHERE 절에서 사용되는 서브쿼리
SELECT Player_name FROM Player WHERE Team_ID IN ( SELECT Team_ID FROM Team WHERE Team_country = 'KOR' );
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
** 제가 겪었던 문제입니다 **
UPDATE 문에서 WHERE 문 안에 서브쿼리를 두 번 써야할 때 쓰는 방법입니다.
오라클 디비를 쓸 때는 몰랐습니다만, 별칭을 줘야 오류가 나지 않더군요.
UPDATE article
SET order_no = order_no + 1
WHERE board_id = 1
AND groupt_no = 14
AND order_no > ( SELECT *
FROM ( SELECT order_no
FROM article
WHERE article_id = 14)t);
어려움을 겪으시는 분들께 큰 도움이 되길 바랍니다.
'Programming' 카테고리의 다른 글
[Java의 정석] 제 2장 변수 - 1.변수 (0) | 2017.06.21 |
---|---|
[Java의 정석] 제 1장 자바를 시작하기 전에 (0) | 2017.06.20 |
[Node.js] node.js 에서 db에 접속하는 방법 (My SQL) (0) | 2017.06.11 |
[Node.js] node js 에서 쿠키를 저장하고, 가져오는 방법 (0) | 2017.05.30 |
[Node.js] Mac 환경에서 Node.js 설치하는 방법 (0) | 2017.05.22 |
댓글