brunch

You can make anything
by writing

C.S.Lewis

by 김유환 Oct 16. 2019

18. 유도된 열 (Derived Column)

SELECT 문을 이용해 테이블의 하나의 열 만들기

배경

지난 글 중간 결과 테이블에서는 SELECT를 통해 얻어진 테이블 결과물에 다시 한번 SELECT 를 적용하는 방법에 대해서 알아보았습니다. 오늘은 이와 매우 유사하지만, 테이블이 아닌 하나의 열을 SELECT 문을 통해 얻어내는 방법을 알아보도록 하겠습니다. 이렇게 얻어지는 열을 '유도된 열' 혹은 'Derived Column' 이라고 부릅시다. 사실 Derived Column 은 공식 용어는 아니지만, Derived Table 과 비슷한 개념이라는 측면에서 이해하기 쉽도록 제가 명명한 이름입니다.


유도된 열을 사용하는 가장 대표적인 예시는 전체 대비 비율을 구하는 작업입니다. 예를 들어, 전체 사용자 중 남자가 몇 % 인지 여자가 몇 % 인지 구하고 싶다고 가정합시다. 이 몇 %를 구하기 위해서는 분자에는 남자 명수, 분모에는 전체 사용자 수를 넣어야 할 것입니다. 지금까지 배운 SELECT 문으로 어떻게 이 값을 구할 수 있을까요? GROUP BY 가 하나의 쿼리 결과값으로 여러 그룹의 통계값을 구하는 기능인것 처럼, 유도된 열 기능 역시 한번의 쿼리로 전체 대비 비율을 구할 수 있는 기능입니다.


상수 열

'유도된 열 기능'을 살펴보기 전에, 상수 열 (Column)에 대해서 알아보도록 합시다. SQL은 SELECT와 FROM 사이에 열의 이름을 입력하는 대신 상수를 입력하는 것을 허용하고 있습니다. 예를 들어, 아래와 같은 쿼리는 에러 없이 실행됩니다.

데이터가 1,008개 저장되어있는 사용자 테이블을 대상으로 위 코드를 실행시켜보시면 아래와 같은 결과 테이블이 나옵니다. 저는 하나의 상수만 입력했는데, 왜 이렇게 많은 데이터가 나올까요? 1, 'a' 라고 구성된 하나의 행만 나오는게 정상적인 행동이 아닐까요?

이유를 이해하기 전에, 몇개의 데이터가 나왔는지에 집중합시다. 위 그림에서 가장 아래 중간을 보면 쿼리 결과값의 갯수를 확인할 수 있습니다. 예제 경우에 1,008개의 데이터가 나왔는데, 바로 사용자 테이블에 저장되어있는 데이터의 개수만큼 결과값이 나온것입니다. 


이 행동을 이해하기 위해서 우리가 이전에 배웠던 가장 간단한 SELECT 문인, 사용자 테이블에서 이름을 가져오는 아래 쿼리를 실행부터 다시 살펴봅시다. 아래 쿼리는 사용자 테이블에 있는 사용자 이름 모두를 가져올 것입니다. 다시 말해, 사용자 테이블에 1008개의 데이터가 있다면, 1008개의 이름 데이터가 결과값으로 도출 될 것입니다.

이 쿼리에 아래와 같이 상수를 추가해서 돌려보면 결과값이 어떻게 될까요? 

아래와 같이 모든 사용자의 이름 앞에 1과 a 가 추가되어 결과값이 도출됩니다. 

이 결과로 봤을때, DBMS 는 다음과 같은 규칙이 있다는 것을 알 수 있습니다.   

1. SELECT 에 열 이름 대신 상수가 입력되어있으면, SQL 실행 결과로 얻어진 모든 행 앞에 해당 상수를 붙임

2. 상수만 존재한다면 데이터 베이스에 저장되어있는 행의 개수만큼 상수를 만들어서 결과 테이블을 만들어냄


상수 열 예제

DMBS는 왜 이런 규칙을 기반으로 상수 열 기능을 제공하는 것일까요? 한가지 예시를 들어보도록 합시다. 아래와 같이 과일 창고에 저장되어있는 상품 재고가 데이터베이스로 관리되고 있다고 가정합시다. 

다음 SELECT 문은 상품 테이블에서 상품명과 해당 상품의 재고를 가져오는 SQL 문입니다.

만약, 전체 재고 상품 중 각 상품이 차지하는 비율을 구하고 싶다면 어떻게 해야할까요? 위 테이블에서 볼 수 있듯이 현재 재고 상품의 총 개수는 6000개 입니다. 각 상품의 재고 숫자를 6000으로 나눠주면 될 것입니다. 이 부분을 SQL 로 실행시키기 위해서는 지난 시간에 배운 중간 결과 테이블과 지금 배우고 있는 상수 열을 활용하면 됩니다.


먼저, 아래와 같이 모든 상품 정보에 6000을 total_number 라는 별명으로 앞에 추가해서 중간 결과 테이블을 만들어 냅니다.

그 다음 numbers를 total_number로 나눠주면 됩니다. 이런 방식으로 상수 열을 이용하면 하나의 쿼리로 비율을 구하는 것이 가능해집니다.


유도된 열 (Derived Column)

위에서 상수 열을 이용해 데이터베이스가 하나의 상수 값이 열에 있으면, 어떤 방식으로 결과값을 만들어내는지 알아 보았습니다. 사실, 상수 열은 데이터베이스의 동작 방식을 이해하기 위해 설명했지, 실제 데이터 분석 실무에서는 거의 사용할 일이 없습니다 (개인적으로는 한번도 없습니다). 그럼에도, 상수 열에 대해서 배운 것은 바로 지금부터 배울 Derived Column을 이해하기 위해서 입니다. 상수 열과 다르게 Derived Column 은 실무에서 매우 유용하게 사용할 수 있습니다.


상수 열 설명의 마지막 예제인 재고 상품의 상품 개수 비율을 구하는 부분부터 이어서 살펴봅시다. 위의 예제는 사과, 복숭아, 수박 단지 3가지 데이터만 존재하기 때문에 쉽게 (눈으로 혹은 계산기로) 6000 이라는 총 개수를 구할 수 있었습니다. 하지만, 데이터가 많은 경우에는 다음과 같이 합을 의미하는 SUM 함수를 이용해서 총 숫자를 구해야할 것입니다.

여기에서 전체 총 합의 값이 나올 것이기 때문에, 이를 활용해서 상수를 입력하면 될 것입니다. 하지만, 하루 이틀이 지나면 전체 총 합의 개수가 달라질 것입니다. 이렇게 되면, 매번 비율을 구하려고 할때마다, 총합을 구하는 쿼리를 돌리고, 여기서 나온 총 합의 개수를 복사해서 비율을 구하는 쿼리를 돌려야하는 불편함이 있습니다. 이를 한번에 할 수 는 없을까요? 이때 사용할 수 있는 것이 바로 Derived Column 입니다.


Derived Column은 위의 SUM 함수처럼 쿼리의 결과가 하나의 열, 하나의 행인 경우에는 해당 쿼리를 상수 열로 사용할 수 있는 것을 의미합니다. 아래와 같이 말이죠.


괄호 안에 들어가 있는 아이템의 총합을 구하는 쿼리의 결과는 1개의 값 (numbers의 총합)으로 구성되어있기 때문에 상수라고 볼 수 있습니다. DBMS 는 상수가 있으면 결과값의 모든 행에 해당 상수를 붙여서 결과를 뽑아내기 때문에, 6000 대신 총 합을 구하는 SELECT 문을 열로 사용할 수 있습니다. 이를 Derived Column 이라고 부릅니다.


이제 마지막으로, 상품 재고 테이블에서 상품의 비율을 구하는 쿼리를 Derived Column 을 이용해서 만들어 봅시다. 상수 대신 해당 상수를 구하는 SELECT 문으로 대체하면 됩니다.

마치며

Derived Column이 지금까지 배운 개념중에 가장 복잡한 축에 속하는 것 같습니다. 하지만, 실무 입장에서 생각해보면 비율을 구하고 싶을 때, Derived Column을 사용하지 다른 예시는 많이 없는 것 같습니다. 비율을 구하고 싶을때는 총합을 구하는 SELECT 문을 하나의 컬럼으로 추가하면 된다 정도로 기억하시면 좋을 것 같습니다. 그러나, 어떻게 이런 결과값이 나오는지 이해하는 것은 문제를 해결하는데 아주 중요합니다. 조금 복잡할 수 있지만, 반복해서 천천히 이해해보시는 것을 꼭 추천합니다. 

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari