Wireframe

SQLite3 – Union 연산

SELECT 문을 사용해서 여러 테이블에서 결과를 조회할 때, JOIN을 사용하여 여러 테이블의 결과를 하나의 테이블로 결합할 수 있는 것을 살펴본 바 있다. JOIN은 두 개의 테이블을 열 방향으로 이어 붙이는 결과를 만들어 낸다. 이와 달리 각 열의 구성이 비슷한 테이블들을 아래/위, 즉 행 방향으로 이어붙이는 방법도 필요할 것이다. 이 때 사용할 수 있는 연산자가 바로 UNION이다. UNION은 하나 이상의 데이터베이스에서 SELECT 쿼리를 사용해 얻을 수 있는 비슷하게 생긴 여러 데이터를 하나의 테이블로 결합할 때 사용한다. 이 때 특이한 점은 연결되는 데이터의 각 행의 연관성과 상관없이 하나의 긴 목록을 만든다는 차이가 있다.

UNION 문법

SELECT 문의 결과가 열과 행으로 구성되는 테이블이라는 점에서 UNION 연산은 두 테이블을 세로로 연결하는 연산이며, 두 개의 SELECT 문 사이에 UNION 연산자가 위치하게 된다. 또 이렇게 구성되는 두 개의 SELECT 문은 하나의 구문으로 합쳐지므로 마지막 SELECT 문 뒤에만 세미 콜론을 붙인다. UNION 연산은 결합이 가능해서 3개 이상의 SELECT 문을 연결할 수도 있다.

SELECT query ...
UNION
SELECT query ...
UNION
SELECT query.... ;

간단한 예를 만들어보자. employees 테이블과 customers 테이블의 이름을 결합하여 회원 및 직원의 명부를 만든다고 생각해보자. 직원과 고객의 이름은 그다지 큰 상관관계가 없으므로 join보다는 UNION이 더 어울린다 할 것이다. 참고로 SQLite에서 문자열 끼리 붙이는 연산자는 || 이다. 첫번째 테이블에서 이름을 합쳐서 칼럼명을 fullname으로 주었다, 그리고 Employee 라고 타입 칼럼을 지정했다. 비슷하게 고객 정보 테이블에서도 이름과, “Customer”라는 고정 문자열 값을 조회하고 이 둘을 UNION 한다.

SELECT firstname || ' ' || lastname AS fullname, "Employee" as type
FROM employees
UNION
SELECT firstname || ' ' || lastname, "Customer"
FROM customers
;

UNION 연산 적용의 규칙

JOIN의 경우에는 실질적으로 두 테이블의 모든 row의 데카르트 곱으로 행을 생성하고, 두 테이블을 연결하는 키를 기준으로 생성된 행에서 필요한 행을 선택하게 된다. 따라서 연산을 적용하는데 있어서 제한이 별로 없다. 하지만 UNION 연산의 경우에는 테이블의 각 행을 그대로 사용하면서 테이블을 연결해야 하기 때문에 연산의 대상이 되는 테이블(쿼리의 결과)에는 일종의 제약이 필요하다. 여기서는 각 SELECT 쿼리의 결과를 편의상 테이블이라고 하겠다.

  1. 연결되는 모든 테이블은 같은 폭 (같은 칼럼 수)을 가져야 한다.
  2. 연결되는 모든 테이블에서의 대응하는 칼럼은 모두 동일한 타입을 가져야 한다.
  3. 첫번째 테이블의 칼럼 이름이 결과의 이름이 된다.
  4. 각 SELECT 쿼리에서의 GROUP BY, HAVING 절은 각각의 쿼리에서만 적용되며, 최종 결과는 단순히 연결만한다.
  5. ORDER BY 절은 최종 결과에 대해서만 적용된다. 따라서 마지막 SELECT 구문에서만 적용해주면 되겠다.

GROUP BY, HAVING 절은 개별 쿼리에서 각각 적용되므로 최종 결합 결과에 대해서 GROUP BY를 적용하고자 한다면 SELECT 문을 중첩하여 서브 쿼리에서 UNION을 사용하고, 그 결과를 다시 조회하면서 GROUP BY를 적용할 수 있다.

이 때, UNION 연산은 앞 뒤의 SELECT 쿼리를 각각 실행한 후, 두 쿼리 결과에서 중복되는 행을 제외하게 된다.UNION ALL은 중복을 제거하는 과정을 거치지 않기 때문에 조금 더 빠르게 실행될 수 있다.

그 외에 비슷한 것

UNION은 두 테이블의 합집합을 구하는 연산으로 볼 수 있는데, 교집합이나 차집합을 구하는 연산도 존재한다. 먼저 INTERSECT 연산자는 두 테이블에서 교집합에 해당하는 행들을 구한다. 사용방법이나 테이블의 제약 사항은 UNION 연산과 동일하다.

EXCEPT 연산은 차집합에 해당하는 행들만 구하는 연산이다.

Exit mobile version