backend/sql (postgres)

sqld: sql 활용 - 표준 조인

seul chan 2018. 11. 6. 20:46

표준 조인 (Standard SQL)

DBMS 벤더별로 문법/용어 차이가 커져서 호환 가능한 기준 제정 ⇒ ANSI/ISO 표준 sql

대표적인 기능들로는

  • STANDARD JOIN (CROSS, OUTER JOIN 등 FROM절 기능)
  • SCALAR SUBQUERY, TOP-N QUERY 등 SUBQUERY
  • ROLLUP, CUBE, CROUPING SETS 등

많은 RDB 이론을 수립한 E.F.Codd 박사 논문에 언급된 8가지 관계형 대수 (일반집합 4개, 순수관계 4개)

일반 집합 연산자

Union(합집합): UNION 기능.

  • union / union all 차이?
  • 일반적인 UNION은 UNION DISTINCT
  • UNION ALL은 중복을 제거하지 않고 합집합, UNION DISTINCT는 중복 제거하여 보여줌
  • 그래서 pk가 절대 중복되지 않는 형태라면 UNION ALL을 쓰는 게 맞음. (둘다 비효율적인 SQL문이라고함. 두 엔터티가 하나의 엔터티여야 하는데 분리운영되었기 때문)
  • 자세한 내용을 다룬 블로그

Intersection (교집합): INTERSECT 기능. 공통집합을 추출

Difference (차집합): 대다수는 EXCEPT 사용, (oracle은 MINUS)

Product (곱집합?): CROSS PRODUCT로 사용. 생길 수 있는 모든 데이터의 조합?

FROM절 JOIN 형태

ANSI/ISO sql에서 표시하는 from절의 JOIN 형태는

INNER JOIN
NATURAL JOIN
USING 조건절
ON 조건절
CROSS JOIN
OUTER JOIN

INNER JOIN

동일한 값이 있는 행만 반환

예제

SELECT Orders.OrderID, Customers.CustomerName
FROM Orders
INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID;

NATURAL JOIN

두 테이블간의 동일한 이름을 갖는 칼럼들에 대해 EQUI(=) JOIN을 수행(?). SQL server 사용불가

데이터 타입/이름이 일치해야만 사용 가능

  • 대부분의 전문가들은 NATURAL JOIN이 위험한 것이며, 그러므로 이것의 사용을 강력하게 비권장하고 있다. 그러한 위험은 다른 테이블에 다른 컬럼으로 동일한 이름을 가진 새로운 컬럼을 무심코 추가하는데서 오는 것이다.

    SELECT * FROM SCHEDULE NATURAL JOIN STADIUM

USING 조건절

—using을 사용하면 equi join에 사용될 열만을 지정 가능. 같은 이름을 가진 칼럼들 중에 원하는 칼럼에 대해서만 선택적으로 조인 가능

SELECT DEPTNO, DEPT.DNAME, DEPT.LOC
FROM DEPT
JOIN DEPT_TEMP USING (DEPTNO);

--kleauge example
SELECT *
FROM SCHEDULE
JOIN STADIUM
USING (STADIUM_ID);

ON 조건절

JOIN 서술부 / 비서술부 분리하여 이해가 쉬우며 칼럼명이 다르더라도 JOIN 사용 가능한 장점

명시적으로 JOIN 조건 구분 가능하여 가장 많이 사용, FROM에 테이블이 많이 사용될 경우 복잡해서 가독성이 떨어질 수도 있음.

-- 예제
-- WHERE절과 혼용
SELECT E.ENAME, E.DEPTNO, D.DEPTNO, D.DNAME
FROM EMP AS E
JOIN DEPT AS D
ON (E.DEPTNO = D.DEPTNO)
WHERE E.DEPTNO = 30;
/* ON 조건절 + 데이터 검증 조건 추가
ON 조건절에 JOIN 조건 외에도 데이터 검색 조건을 추가할 수는 있으나, 검색 조건 목적인 경우는 WHERE 절을 사용할 것을 권고
*/
SELECT E.ENAME, E.MGR, D.DEPTNO, D.DNAME
FROM EMP AS E
JOIN DEPT AS D
ON (E.DEPTNO = D.DEPTNO AND E.MGR = 7698);
-- 다음과 같은 결과
SELECT E.ENAME, E.MGR, D.DEPTNO, D.DNAME
FROM EMP AS E
ON (E.DEPTNO = D.DEPTNO)
WHERE E.MGR = 7698;

/*
팀과 스타디움 테이블을 스타디움 ID 로 JOIN 하여 
팀이름, 스타디움 ID, 스타디움 이름을 찾 아본다.
*/
SELECT TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME
FROM TEAM
JOIN STADIUM
ON (TEAM.STADIUM_ID = STADIUM.STADIUM_ID);
-- 공통적으로 STADIUM_ID를 가지고 있기 때문에 USING 조건절 사용 가능
SELECT TEAM_NAME, TEAM.STADIUM_ID, STADIUM_NAME
FROM TEAM
JOIN STADIUM
USING (STADIUM_ID)

CROSS JOIN

일반 집합 연산자의 PRODUCT 개념으로 테이블간 JOIN 조건이 없는 경우 생길 수 있는 모든 데이터 조합. (M*N개의 데이터 조합이 발생).

정상적인 db 모델이라면 CROSS PRODUCT가 필요한 경우가 별로 없음. 간혹 튜닝을 위해서 사용.

OUTER JOIN

INNER JOIN과 다르게 JOIN 조건에서 동일한 값이 없는 행도 반환할 때 사용 가능

LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN

  • FULL OUTER JOIN은 FULL JOIN으로도 사용 가능, UNION 기능과 같이 중복되는 데이터는 삭제