본문 바로가기

SQL 기초

SQL 처음으로 배우기 - JOIN

 앞의 글 'SQL 처음으로 배우기 - SELECT / FROM / WHERE / ORDER BY'를 통해 단 몇 분도 안되어 데이터베이스에서 데이터 뽑는 것을 배웠다. 연봉 1위로 3천3백만 불을 받은 그 선수는 누구일까?

  아마 SQL 편집기를 다루는게 익숙하지 않아 버벅거렸을 수는 있으나, SQL 쿼리의 문법이 어렵지는 않았으리라. SQL 편집기를 다루는 법에 대해서는 곧 별도의 글을 작성할 예정이다. 우선 그전에 SQL 쿼리가 어떤 것이 있고, 얼마나 간단한지 정도 알고 가자. 이번 글도 마찬가지로 얼마나 간단하게 사용될 수 있는지를 보기 위한 글이다. 

 데이터베이스에서 데이터를 뽑을 때, 하나의 데이터 테이블에서만 뽑는 경우는 거의 없다. 대부분 연관되어 있는 다른 테이블과 같이 연결하여 뽑게 된다. 연봉 1위인 선수의 'playerID'는 'salaries' 테이블에 있지만, 선수의 이름은 그 테이블에 없다. 연관이 있는 테이블은 어디에서 찾을 수 있을까? 

 

연관 데이터 테이블 찾기

 

1. 스키마(Schema)

 '데이터 분석' 카테고리의 글인 '데이터 분석 2단계: 준비 (Preparation) - DB, 데이터베이스' 에서 이미 답을 언급했다. 바로 '스키마'이다. '스키마(Schema)'에는 어떤 테이블에 어떤 데이터들이 들어 있는지, 각 테이블들 간의 관계는 어떠한지 등에 대한 설명이 담겨 있다.

※ 스키마에 대한 정확한 설명은 아니지만, 대략적인 부분만 이해하고 넘어가자.

 데이터베이스를 만들어 놓기만 하면 끝이 아니다. 그 이후에도 새로 생성 및 수정되기도 하고, 분석을 위해 다수의 사람이 접속하여 데이터를 뽑아야 하는 상황도 생긴다. 따라서 다음 작업자 또는 접속자를 위해 일종의 '설명서'가 필요한 건 지극히 당연한 일이다. 그렇지 않으면 접속하는 사람마다, 작업자마다 제 각기 데이터베이스를 파악하기 위해 각자의 시간이 소요될 테고, 나중에 중복 데이터를 만들어 올려놓는 일이 생길 수도 있다.

 거창하게 스키마라는게 아니어도, 어딘가에 데이터베이스 관리자가 만든 테이블명 리스트 및 각 테이블 속성/필드 리스트가 엑셀 파일이든, 아니면 데이터베이스 내 별도의 테이블로 있을 것이다. 대부분의 회사는 데이터베이스의 테이블 리스트 최상단에 그런 테이블을 배치해 놓는다. 

 

2. ER 다이어그램, (ERD, Entity Relationship Diagram)

Entity 간의 관계도인 ER Diagram 또는 ERD를 통해서도 알 수 있다. 무료 SQL 편집기인 DBeaver는 데이터 테이블을 선택했을 때, Properties/Data/ER Diagram 3개의 탭을 통해 테이블에 대한 내용을 확인할 수 있다. 이 중에서 DR Diagram에 가 보면, 선택한 테이블과 연관이 있는 테이블 및 그 테이블에 있는 속성(항목 값) 들을 볼 수 있다.  

 각 탭에 대한 자세한 설명은 별도의 글을 통해 하도록 하겠다. 우선 ER Diagram 탭을 선택하면 아래와 같은 ERD를 볼 수 있다. Lahman Database에 있는 모든 테이블들이 나와있고, 각 테이블 내의 속성들도 볼 수 있다. 우리가 궁금했던 'playerID'에 대한 단서를 찾기 위해, 'playerID'를 클릭하면 아래와 같이 모든 테이블 중 'playerID'를 가지고 있는 테이블들에 녹색 하이라이트 되어 표시된다. 

 찾았다. 'people'이라는 테이블에 'playerID'가 Key값으로 있는데, 거기에 'nameLast', 'nameFirst'가 있으니 그걸 뽑아보면 되겠다. 

 

 

복수의 테이블에서 데이터 추출: JOIN

 JOIN에 대한 자세한 설명은 별도의 글을 통해 하겠다. 여기서는 JOIN이 우리가 원하는 'salaries' 라는 테이블과, 'people'이라는 복수의 테이블에서 데이터를 뽑기 위한 SQL 문법이라는 점만 알고 가자. 

 간략히 JOIN에 대해 설명하자면, 중학교 수학 첫 수업 때 배웠던 벤다이어그램에 대해 기억해야 한다. (아직도 첫 수업이 다이어그램에 대한 것인지는 모르겠다.) 

 각 테이블을 다이어그램이라고 보면, 'people' 테이블에 있는 Key값인 'playerID'를 들여다 보았을 때, 'salaries' 테이블에 완전히 그 'playerID'값들이 전부 있을 수도 있고, 일부만 있을 수도 있다. 즉, 완전한 중복일 수도 있고, 'people'에는 없는 'playerID'가 'salaries'테이블에는 있을 수도 있고, 그 반대일 수도 있다. 

 'salaries' 테이블에 있는 'palyerID'를 기준으로 'people' 테이블에 있는 동일 'playerID'값을 갖는 레코드만 보고자 한다면, 'INNER JOIN' (벤다이어그램의 교집합)을 써야한다. 일반적으로 JOIN만 쓰면 INNER JOIN이 된다.

이걸 쿼리로 작성해보면 아래와 같다.

SELECT salaries.yearID
	, salaries.playerID 
	, salaries.salary
	, people.nameFirst
	, people.nameLast
FROM salaries INNER JOIN people ON salaries.playerID = people.playerID 
WHERE salaries.yearID = 2016
ORDER BY salaries.salary DESC;

  'salaries' 테이블을 기준으로 'people'을 연결하는데, 'salaries'의 'playerID'와 'people'의 'playerID'가 정확하게 일치하는 레코드만 뽑는다. 

 결과는 아래와 같다. 2016년에 연봉 3천3백만 불로 메이저리그 연봉 1위였던 선수는 우리에게도 익숙한 클레이튼 커쇼(Clayton Kershaw) 선수이다. 과거에 LA 다저스에서 류현진 선수와 같이 선발투수진에 있었던 선수이다. 

 

 커쇼가 류현진 선수와 같이 2013년 시즌에 좌완투수로 활약했었던 기억이 있는데, 그때의 연봉은 얼마였고, 연봉이 어떻게 변해왔을까? 다음 글을 통해 알아보자.