티끌모아 로키산맥 🏔
search
로ᄏl
배움에 끝은 없다... 개발 또한 그러하다.
Today
Yesterday
http://www.sqlprogram.com/Basics/sql-join.aspx
위 글들을 참고하였습니다.
현재 진행중인 프로젝트에서 테이블을 3개, 4개 join하라는 요구조건이 있었다. SQL로 간단한 CRUD 정도만 진행하다보니 join의 개념을 잊고있었다. (또 이렇게 되새김질 하는 것 아니겠는가? 부디 이번에는 오랫동안 기억에 남기를 바란다)
SELECT문은 하나 이상의 테이블로부터 데이터를 가져올 수 있다. 복수의 테이블로부터 데이타를 가져오기 위해서는, FROM절 뒤에 복수의 테이블을 나열하면 된다. 이때, 테이블들이 서로 연관을 맺고 이들로부터 특정 조건의 레코드셋들을 선별하게 되는데, 이를 테이블 조인이라 한다. 테이블 조인에는 Cross Join, Inner Join, Outer Join 등이 있으며, Cross Join은 테이블A의 모든 레코드들에 대해 테이블B의 모든 레코드가 맴핑되는 것으로, 테이블A에 10개 레코드가 있고, 테이블 B에 5개 있다면, 총 10 x 5 = 50개의 레코드를 출력한다. Inner Join은 테이블A의 특정 컬럼값이 테이블B의 지정 컬럼값과 일치하는 레코드만을 선별하는 경우에 사용된다. Outer Join은 Inner Join과 마찬가지로 조인 조건을 만족하는 레코드들을 출력하지만, 추가로 일치하지 않는 레코드들도 함께 출력해 준다.
Inner Join은 복수 테이블들이 조인 조건을 모두 만족하는 레코드들만 선별하는 조인이다.
아래와 같이 두가지 방법으로 표현할 수 있다.
(1) Inner Join...On 문 FROM TabA INNER JOIN TabB ON TabA.Col = TabB.Col (2) FROM...WHERE절에서 조인 조건식 사용 FROM TabA,TabB WHERE TabA.Col = TabB.Col |
예제
-- Orders 테이블과 OrderDetails 테이블을
-- Order ID로 조인한 예
-- 두 테이블에 동일 컬럼이 있는 경우
-- 테이블명을 명시적으로 사용한다.
SELECT Orders.ID, OrderDetails.*
FROM Orders INNER JOIN OrderDetails
ON Orders.ID = OrderDetails.ID
WHERE Orders.OrderDate >= '1/1/2012'
-- 테이블 Alias를 사용하여
-- 위의 문장을 간략히 다음처럼 표시
SELECT o.ID, d.*
FROM Orders o INNER JOIN OrderDetails d
ON o.ID = d.ID
WHERE o.OrderDate >= '1/1/2012'
Cross Join은 복수 테이블의 모든 레코드를 M x N 식으로 모두 출력하는 것으로, 만약 테이블A가 10개의 레코드가 있고, 테이블B가 5개의 레코드가 있다면, 10 x 5 레코드 즉 총 50개의 조합을 출력한다. Cross Join은 특별한 조인 조건을 지정하지 않고, 복수 테이블명을 FROM절에 나열하면 된다. (이해가 쉽다고 판단하여 따로 예제는 안들겠다)
SELECT * FROM Class, Score |
복수 테이블에 모든 조인 조건이 만족되지 않더라도 한 테이블의 모든 데이터는 출력되게 하려면 Outer Join을 사용한다. 매칭 데이터가 없는 부분은 NULL로 표시될 것이다. Outer Join은 모든 데이터를 출력하는 테이블의 위치에 따라 Left Outer Join, Right Outer Join, 그리도 양쪽 테이블의 모든 데이터가 기본적으로 출력되는 Full Outer Join이 있다.
예제
-- City명은 매출여부와 상관없이
-- 출력. 매출없는 경우 합계란은 NULL
--
SELECT c.Name, SUM(s.Total) '합계'
FROM City c LEFT OUTER JOIN Sales s
ON c.Code = s.CityCode
GROUP BY c.Name
-- Outer Join 결과 예 --
Name 합계
------------------- -----------
서울 264
부산 238
대전 232
제주 NULL
(위에서 언급하지는 않았지만 이런 Join도 존재한다)
Self Join이란 FROM절에 하나의 테이블을 Table Alias를 통하여 두번 참조한 후, 자신의 테이블을 마치 다른 테이블인 것 처럼 조인하는 것이다. 아래 예제는 Self Join을 통해 Emp 테이블에서 Boss가 Kim인 모든 종업원을 출력하는 예이다.
예제
SELECT e.EmpID, e.Name, b.Name AS Boss
FROM Emp e, Emp b
WHERE e.MgrId = b.EmpId
AND b.Name = 'Kim'
SELECT ST.STADIUM_NAME, SC.STADIUM_ID, SCHE_DATE, HT.TEAM_NAME, AT.TEAM_NAME, HOME_SCORE, AWAY_SCORE
FROM SCHEDULE SC
JOIN STADIUM ST
ON SC.STADIUM_ID = ST.STADIUM_ID
JOIN TEAM HT
ON SC.HOMETEAM_ID = HT.TEAM_ID
JOIN TEAM AT
ON SC.AWAYTEAM_ID = AT.TEAM_ID
WHERE HOME_SCORE >= AWAY_SCORE +3
(테이블에 대한 구체적인 소개는 따로 안하겠다. 그냥 3개의 테이블(SCHEDULE, STADIUM, TEAM)이 있다는 사실만 파악하면 된다 마지막에 self join을 써서 같은 테이블을 사용했다)
원래 WHERE 조건절로 각 테이블을 연결시켜주는 column의 동등 조건을 나열하면서 (수동적인) join을 진행하려고 하였는데... 지나가면서 본 내용중에 성능적인면에서 WHERE로 join 결과를 만들어 내는 것은 조회 횟수가 많기 때문에(결국 모든 데이터를 조회 해야하기 때문이라고 했던 것 같다) 성능적인 측면에서 join이 더 좋다고 했던 것 같다. (나를 너무 신뢰하지는 말아줬으면 한다)