우리는 SQL에서 두 개의 테이블을 맞출 수 있다는 것을 알고 있습니다. 바로 JOIN이라는 개념을 써서요. 그러면 3개 아니면 그보다 더 많은 테이블을 LEFT JOIN 할 수 있을까요? 네, 할 수 있어요. 이 글은 몇 개의 테이블을 LEFT JOIN 하는 방법에 대해서 알아보도록 하겠습니다. 또그과정에서우리가우연히놓치는개념에대해서도함께이야기해보려고합니다.
LEFT JOIN이란?LEFT JOIN이 뭐였는지 돌아보는 것부터 시작해볼까요? SQL의 조인 중 INNER JOIN을 기억하시나요? INNER JOIN은 조인하는 두 테이블에 공통적으로 존재하는 값만 반환합니다. 반면 LEFT JOIN의 경우 왼쪽 테이블에서는 모든 값을 오른쪽 테이블에서는 왼쪽 테이블과 일치하는 값만 반환합니다. 그러면 어떤 값이 왼쪽 테이블에는 존재하지만 오른쪽 테이블에는 존재하지 않는 경우 두 테이블을 LEFTJOIN한 결과는 어떻게 될까요? LEFT JOIN을 하는 이상 좌측 테이블이 주인공이기 때문에 좌측 테이블에서 가져온 행 값은 빠짐없이 모두 반환되지만 우측 테이블에서 가져온 행 값은 존재하지 않기 때문에 NULL 값으로 반환됩니다. 그러면 오른쪽 테이블에 있는 값이 왼쪽 테이블에는 존재하지 않으면 두 테이블을 LEFTJOIN을 한 결과는 어떻게 될까요? 결과 테이블에는 그 값이 등장하지 않을 것입니다. 왜냐하면 주인공은 왼쪽 테이블이기 때문입니다.

아래는 LEFT JOIN의 가장 기본적인 구문입니다.SELECT column namesFROM table1 AS t1LEFT JOIN table2 AS t2ON t1.common_column=t2.common_column; LEFT JOIN은 SQL을 통한 분석을 할 때 상당히 자주 합니다. 왜냐하면 이것은 두 테이블 사이의 차이를 파악하게 되면 상당히 쉬워지기 때문입니다. 즉, 특정 테이블에는 값이 존재하지만 다른 테이블에는 존재하지 않는 값을 구분하여 올릴 수 있기 때문입니다. 만약 왼쪽 테이블에는 값이 존재하는데 오른쪽 테이블에는 존재하지 않는 값만 따로 조회하고 싶다면 어떤 방법으로 쿼리문을 구성해 보는 것이 좋을까요. LEFT JOIN을 한 후에 WHERE 절을 추가해서 오른쪽 테이블열 값이 NULL인 행을 추가로 필터링해 달라고 요청하면 됩니다.실제 비즈니스 케이스를 통해 이야기해보도록 하겠습니다. 우리가 온라인 서점을 운영하고 있다고 가정해 보겠습니다. 우리는 지난 6개월 간의 주문 내역을 통해 해당 기간 동안 구매 활동이 줄어든 고객, 즉 무효 고객이 누구인지 알고 싶습니다. 하지만 무효 고객 리스트만 보는 것이 아니라 최근에 구매 활동이 있었던 활성 고객 리스트도 함께 보고 싶습니다. 즉, 모든 고객의 정보를 나열하고 그 고객이 구입을 했는지 안 했는지 알 수 있도록 결과 테이블이 구성되어 있습니다. 지금 설명한 예시가 바로 LEFT JOIN을 사용하기에 아주 좋은 예시입니다.우리 가게 안의 데이터베이스 테이블을 살펴보도록 합시다.1.고객 테이블(customers)idfirst_namelast_namegenderage customer_since1 Daniel Black M342014-10-132 Erik Brown M252015-06-103 Diana Trump F392015-10-254 Anna Yao F192017-02SELECTc.id, c.first_name, c.last_name, c.gender, c.age, c.customer_since, s.date AS sales_date, SUM(s.amount)AS total_spentFROM customers, 구매액수에서 구매액수 제외, AS cLEFT JO 구매일과 구매액은 sales 테이블에서 가져와야 할 일이 벌어집니다. 해당 쿼리 문을 실행하고 보면 아래와 같은 결과를 얻을 수 있습니다. 이중 볼드 처리된 2개 행은 LEFT JOIN만으로 되는 결과입니다. 만약 위 크오림은으로 LEFT JOIN대신 INNER JOIN을 사용하면 테이블 양쪽에 공통으로 존재하는 값만 반환하므로, 구매액의 정보가 없는 아이 디 1과 5는 조회되지 않습니다.idfirst_namelast_namegenderagecustomer_sincesales_datetotal_spent1DanielBlackM342014-10-13[NULL][NULL]2ErikBrownM252015-06-102019-10-0112.993DianaTrumpF392015-10-252019-09-0214.994AnnaYaoF192017-02-202019-10-0115.755ChristianSandersM422018-01-31[NULL][NULL] 보시다시피, 해당 기간에 무슨 구매 활동이 없었던 고객의 경우 total_spent열의 값이 존재하지 않습니다. 그러나 그들의 고객 정보가 주인공의 테이블인 왼쪽 테이블 customers에 존재했기 때문에 그들의 아이디, 이름, 성별, 연령 등의 정보가 조회 되었습니다. 그러나 오른쪽 테이블에서 가져오던 그들의 구매 날짜와 구매 금액에 대한 데이터가 존재하지 않기 때문에 전부 NULL값이 나왔습니다. 이것이 LEFT JOIN의 모습입니다. 왼쪽 테이블과 공통되는 값이 없다며 왼쪽 테이블 내의 행을 건너뛰고 버리지 않습니다.지금은 더 복잡한 경우를 체크합니다.
하나의 쿼리 중에 몇 차례의 LEFT JOIN분석을 하면 2개의 탁자만으로는 분석이 어렵고 3개 이상의 테이블을 조인해야 하는 상황이 발생합니다. 그래서 이번에는 3개 이상의 테이블을 LEFT JOIN하는 모습을 보이고 보냅니다. 아래 테이블을 보세요.3. 프로모션 테이블(promotions)idcampaigncustomer_iddate1SMS_discount1022019-09-012SMS_discount1032019-09-013SMS_discount1052019-09-01우리는 해당 테이블을 활용하고 최근 진행한 프로모션이 고객의 구매에 영향을 미쳤는지 궁금합니다. 이를 구하려면 고객(customers)매출(sales)프로모션(promotion)총 3개의 테이블을 조인해야 합니다. 우리가 원하는 정보가 세개의 탁자에 흩어지고 있기 때문입니다.SELECTc.id, c.first_name, c.last_name, c.gender, c.age, c.customer_since, s.date AS sale, p.date AS promotionFROM customers AS cLEFT JOIN sales AS sON c.id=s.customer_idLEFT JOIN promotions AS pON c.id=p.customer_id의 위 쿼리를 실행하면 다음과 같은 결과를 얻습니다.idfirst_namelast_namegenderagecustomer_sincesalepromotion1DanielBlackM342014-10-13[NULL][NULL]2ErikBrownM252015-06-102019-10-012019-09-013DianaTrumpF392015-10-252019-09-022019-09-014AnnaYaoF192017-02-202019-10-01[NULL]5ChristianSandersM422018-01-31[NULL]2019-09-01LEFT JOIN을 사용했기 때문에 고객의 구매 및 프로모션에 참석 여부와 상관 없이 모든 고객 목록을 조회할 수 있었습니다.만약 3개의 테이블을 INNER JOIN에 맞췄다면 결과 테이블은 구입도 하고 뮤직에도 참여한 고객에게만 조회되고 있었을 거에요.LEFT JOIN은 1개의 탁자에는 값이 있지만 다른 테이블에는 그 값이 없어도 여전히 기존 행을 조회할 수 있습니다.고객 1을 봅시다. 고객 1은 구입도 하지 않고 뮤직 메시지를 받은 적도 없습니다.그럼에도 불구하고 우리는 고객 1에 관한 기본적인 정보를 물어보지 않았습니까?이것이 바로 LEFT JOIN의 힘입니다.”고객 4″도 봅시다.이 고객의 경우, 구입 이력은 있지만, 프로모션 메시지를 받은 적은 없습니다.고객 5명의 경우는 구입 이력은 없지만 뮤직 메시지는 받았습니다.마지막으로 구입 이력도 있는 프로모션 메시지도 받은 고객 2와 3번 결과 테이블에서 찾을 수 있습니다.이들의 고객의 결과는 INNER JOIN을 사용한 경우도 얻는 결과가 됩니다.
이 테이블의 결과를 얻기 위해서 작성한 쿼리 문에 돌아오면 우리는 2번째 테이블(sales)와 3번째의 테이블(promotions)을 조인하기 위해서 첫번째 테이블(customers)과 겹치는 줄을 썼어요. 그렇지만 첫 행과 겹치는 줄을 발견하고 조인해야 하는 것은 아닙니다.3번째 테이블을 조인하기 위해서, 2번째의 공통한 줄을 써도 괜찮겠어요.이하의 예에서 그 케이스를 다루어 볼까요?
이번에는 고객이 반응이 좋은 책의 장르에 대해서 알고 싶습니다.이러한 분석은 고객에게 책 추천과 같은 개인화된 경험을 제공할 수 있기 때문에 매우 유용한 정보입니다.해당 분석을 위해 3개의 테이블에서 각각 다른 데이터를 가져올 예정입니다. 테이블은 customers 테이블, sales 테이블, books 테이블입니다.이미 customers와 sales 테이블을 조인한 적이 있기 때문에, 세 번째 테이블인 books만 추가로 조인하는 과정을 봐주시기 바랍니다.
4. 책 테이블 (books)idnameauthorgenrequantityprice1The Lord of the RingsJ. R. R. Tolkienfantasy712.992LolitaVladimir Nabokovnovel414.994The HobbitJ. R. R. Tolkienfantasy1010.755Death on the NileAgatha Christiedetective89.75쿼리문은 아래와 같습니다.SELECTc.id,c.first_name,c.last_name,s.date AS sale,b.name AS book,b.genreFROM customers AS cLEFT JOIN sales AS sON c.id = s.customer_idLEFT JOIN books AS bON s.book_id = b.id;ᅳᆫ customers, sales, books ᅳᆯᄋ rᅳ, 주문의 특정 장르가 된 것, 주문의 형태가 된 것, 최근 들어 LEFT JOIN r. 테이블의 구성을 보면,idfirst _ namelast _ namesalebookgenre 1 DanielBlack [ NULL ] [ NULL ] 2 ErikBrown 2019 – 10 – 01 The Lord of the Ringsfantasy 3 DianaTrump 2019 – 09 – 02 Lolitanovel 4 AnnaYaLL ] [ NULL ] 2 ELLBrown 2019 – 10 – 01 ] で も 、 僕 たち が INNER JOIN 。