[SQL] 10. 데이터 연결 (JOIN)

2025. 2. 21. 16:29·SQL/BigQuery
목차
  1. 1. JOIN 개념 이해
  2. 포켓몬 데이터 예시
  3. JOIN이 필요한 이유
  4. 2. 다양한 JOIN 함수
  5. 3. JOIN 쿼리 작성 방법
  6. 작성 흐름
  7. 쿼리 문법
  8. 헷갈릴 만한 부분
  9. 4. 연습문제



1. JOIN 개념 이해

  • 간단히 말해, 서로 다른 데이터(테이블)를 연결하는 작업
    • 처음에 좀 어렵게 느껴질 수 있는데, 문제 많이 풀어보면서 체화하는 게 좋음!
  • 연결하려는 테이블들에 공통으로 존재하는 컬럼(=Key)이 있어야 JOIN 가능!
    • 보통 id 값을 많이 사용하고, 특정 범위(ex. Date)로도 JOIN 가능함

포켓몬 데이터 예시

ex) 트레이너 데이터(trainer)와 포켓몬 데이터(pokemon)를 연결해보고 싶다면?

  • 두 데이터를 연결할 수 있는 공통값(key)이 없어서 불가능함.
    • (id가 있다고 생각할 수 있지만, 엄밀하게는 각각 trainer_id, pokemon_id로 다른 값이라서 안 됨. 바로 연결하려면 trainer 테이블에 pokemon_id와 같은 컬럼이 있어야 함 → 그래서 보통 연결할 수 있는 테이블인지 파악할 때 xxx_id, xxx_name 같은 컬럼이 있나 확인함)

  • 트레이너가 포획한 포켓몬 데이터(trainer_pokemon) 를 사용하면 연결 가능함! (trainer_id를 trainer 테이블의 id와 연결, pokemon_id를 pokemon 테이블의 id와 연결)
    • ➔ 이러면 이제 단일 자료로는 할 수 없던 분석이 가능해짐 (ex. 트레이너는 선호하는 포켓몬 타입대로 실제 포켓몬을 잡을까?)

  • 만약 (기준 테이블이 trainer_pokemon이라는 가정 하에) trainer_id와 id를 연결(JOIN)할 경우, trainer_pokemon의 우측에 trainer 테이블의 정보들이 추가됨 (=trainer 테이블의 컬럼들이 옆에 추가됨)
    • 이때 trainer_id, id가 JOIN Key라고 보면 됨

 

JOIN이 필요한 이유

👨‍🏫왜 굳이 여러 테이블을 놔두고 JOIN으로 연결해서 사용할까? 그냥 한 번에 다 저장하면 안 되는 걸까?
➔ 데이터가 저장되는 형태를 이해하면 답이 나옴.
  • 관계형 데이터베이스(RDBMS) 설계 시 정규화 과정을 거침.
    • 정규화란 중복을 최소화하도록 데이터를 구조화하는 것
    • ex) User 테이블에는 사용자 관련 정보만, Order 테이블에는 주문 관련 정보만
  • 그런데 모든 정보(컬럼)을 한 번에 저장하면 중복이 엄청 많이 발생하게 됨!
    그래서 다양한 테이블에 나눠서 저장해두고, 필요할 때 연결(JOIN)해서 사용하는 것이 개발 관점에서 더 좋음 !
  • 최근에는 데이터 웨어하우스에서 JOIN + 필요한 가공을 해서 다시 저장해두는 방식을 많이 사용함
    • = "데이터 마트"
    • 가장 기본적인 데이터 마트 예시: Order 테이블 → 일자별, 주문타입별, 지역별, 주문 건수, 매출

 

2. 다양한 JOIN 함수

  • JOIN을 수행하는 여러 방법이 있음
  • 처음에 어렵다면 LEFT JOIN만 주로 사용해도 충분함! (여기서 조건 걸면 INNER JOIN도 가능)

INNER JOIN : 두 테이블의 공통 요소만 연결

LEFT JOIN : 왼쪽 테이블 기준으로 연결 (왼쪽 테이블 그대로 두고, 오른쪽 중에 겹치는 행만 결합)

RIGHT JOIN : 오른쪽 테이블 기준으로 연결 (오른쪽 테이블 그대로 두고 , 왼쪽 중에 겹치는 행만 결합)

FULL JOIN : 양쪽 기준으로 모두 연결 (KEY 전부 가져오고, 왼/오 전부 결합)

CROSS JOIN : 두 테이블 각각의 요소를 곱함 (각 행끼리 모든 조합을 생성하며 결합)

 

 

👨‍🏫판단하기 헷갈릴 때는 벤다이어그램으로 그려서 생각해보는 걸 추천!

ex) A 테이블과 B 테이블 교집합인 데이터도 필요하고, A에만 있는 것도 필요해 => LEFT JOIN 사용!

출처 : 카일스쿨, 초보자를 위한 BigQuery(SQL) 입문

3. JOIN 쿼리 작성 방법

작성 흐름

  1. 테이블 확인 : 테이블에 저장된 데이터 특징, 컬럼 확인
  2. 기준 테이블 정의 : 가장 많이 참고할 테이블을 정의 (ex. LEFT JOIN일 경우, left로 어떤 테이블을 쓸 것인지)
       = Row 개수가 적으면서 내가 원하는 정보를 최대한 포함하는 테이블
  3. JOIN Key 찾기 : 여러 테이블과 연결할 Key 정리 (ON 위치에 작성함)
  4. 결과 예상하기 : 결과 테이블을 예상해서 손/엑셀로 작성해보기 (=정답지 역할. 익숙해지면 생략 가능)
  5. 쿼리 작성 및 검증 : 쿼리를 실행하고, 예상했던 결과와 동일한 결과가 나왔는지 확인

쿼리 문법

  • FROM 하단에 JOIN할 테이블을 작성하고, ON 뒤에 공통 컬럼(Key)을 작성
    • 테이블 이름 길면 별칭(Alias) 자주 사용함!
  • ⚠️CROSS JOIN은 Key 없어도 연산이 돼서 ON 필요 없음!
    • INNER, LEFT, RIGHT, FULL 다 동일하게 사용하는데, CROSS JOIN만 다름!
SELECT
    A.col1,
    A.col2,
    B.col11,
    B.col12
FROM table1 AS A
LEFT JOIN table2 AS B 
ON A.key = B.key -- 별칭으로 간단히 입력
  • 그리고, JOIN은 연달아 수행할 수도 있음
    • ex) trainer_pokemon 테이블에 trainer 테이블을 연결 & 거기다 다시 pokemon 테이블을 연결
    • BigQuery 실습 과정은 더보기 참고
SELECT
  tp.*,
  t.* EXCEPT(id), -- 어차피 tp에 있으니 제외
  p.* EXCEPT(id) -- 어차피 tp에 있으니 제외
FROM basic.trainer_pokemon AS tp
LEFT JOIN basic.trainer AS t
ON tp.trainer_id = t.id -- 여기까지 한 덩어리
LEFT JOIN basic.pokemon AS p -- 그리고 다시 JOIN 수행
ON tp.pokemon_id = p.id
더보기

1) trainer_pokemon 테이블에 trainer 테이블을 연결

2) 이어서 pokemon 테이블을 추가로 연결

3) id 컬럼이 3번이나 중복되니까 EXCEPT로 제외해주기


 

헷갈릴 만한 부분

1. 여러 JOIN 중 어떤 것을 사용해야 할까?

  • 하려는 작업 목적에 따라 다름.
    • 교집합이 필요하면 INNER, 모든 조합이 필요하면 CROSS, 그게 아니면 LEFT/RIGHT
  • 처음엔 하나를 계속 활용하는 걸 추천
    (ex. LEFT 쓰다가 오른쪽에 붙은 테이블에 NULL 생기면, WHEREcol1ISNOTNULL 해서 INNER JOIN과 같은 결과를 얻을 수 있음!)
  • 👨‍🏫쿼리 작성 템플릿에 꼭 예상 결과를 쓰고, 중간 결과도 적어보면서 단계적으로 실행하는 연습하기!

2. 어떤 Table을 왼쪽에 두고, 어떤 Table을 오른쪽에 둬야 할까?

  • LEFT JOIN은 기준이 되는 테이블을 왼쪽에 둠
  • 기준 = '내가 필요한 데이터 요소가 빠짐없이 있는가'로 판단하기!
    • ex1) 주문한 유저들의 정보가 필요한 경우 : order 테이블을 기준으로 두고 user 테이블을 붙이면, 애초에 주문한 유저들의 정보만 가져올 수 있음
    • ex2) 주문 안 한 유저들을 확인하고 싶은 경우 : user 테이블을 기준으로 두고 order 테이블 붙이면, NULL값이 발생할 거임. 그럼 IS NULL 조건 걸어서 주문 안 한 정보들을 확인할 수 있음
    • 왼쪽에 어떤 테이블을 두느냐에 따라 어떻게 달라지는지 예상 결과를 써보는 연습하자!

3. 여러 Table을 연결할 수 있는 걸까?

  • JOIN 개수에 한계는 없지만, 너무 많이 하는 것도 좋지 않음 (3~5개까지가 적절하다고 하심)
  • 여러 개 연결하는 경우 WITH를 활용하면 가독성 있게 쿼리 작성 가능 (나중에 배울 예정)

4. 컬럼은 모두 다 선택해야 할까?

  • 역시 하려는 작업에 따라 달라짐.
  • 처음엔 JOIN 잘 됐는지 보기 위해 많은 컬럼 select 해도 되지만, 사용하지 않을 컬럼을 계속 select하면 BigQuery 비용이 그만큼 부과됨.. (데이터 크면 1번 실행하는 데 몇 만원이 들 수도,,,)

5.  NULL이 대체 뭘까?

  • NULL = 값 자체가 없음. 알 수 없음. 🆚 0 또는 공백("")과 다름!!
  • JOIN 시 연결할 값이 없으면 생기게 됨

 

4. 연습문제

문제 1. 트레이너가 보유한 포켓몬들은 각각 얼마나 있는지 알 수 있는 쿼리를 작성해주세요. 단, 포켓몬 이름이 명시되어야 합니다. (*보유했다의 정의는 status가 'Active', 'Training'인 경우를 의미 & 'Released'는 방출했다는 것을 의미)

 

▶내 풀이 과정

더보기

1) 데이터 확인

  • 일단 status가 "Active" 또는 "Training"인 경우를 출력해봄

2) trainer_pokemon을 기준으로 두고 pokemon을 LEFT JOIN으로 연결

  • 그리고 kor_name까지 같이 나오도록 출력해봄

2) 방금 출력한 걸 원본으로 하도록 서브쿼리로 감싸고, COUNT & GROUP BY 사용해서 집계!

  • 일단 답은 맞는 듯?

▶강사님 풀이 과정✅

더보기

1) 데이터 확인

  • 내 풀이와 동일하게 trainer_pokemon만 WHERE 걸어서 조회

2) tp 테이블 자체를 'WHERE 조건 걸어둔 테이블'로 줄여둔 뒤, LEFT JOIN으로 결합!

3) 조회 한 번 해서 확인한 뒤, 똑같이 COUNT & GROUP BY 사용해서 집계

  • ⭐단, JOIN한 테이블에 중복된 컬럼()이 있을 때는 어떤 테이블인지 반드시 명시해줘야 함(tp.tp.)

 

👨‍🏫JOIN을 먼저 하는 게 좋을까, WHERE로 조건을 먼저 걸어두는 게 좋을까?

  • 일단 row 수를 줄여두고 시작하는 게 연산량이 줄어듦! 그러니 WHERE을 먼저 쓰자! (단, 줄이고 써도 작업 목적에 문제가 없어야 함!) 🆚내가 짠 코드는 JOIN을 먼저 한 셈이네..
  • 그리고 지금 쿼리가 좀 복잡하고 길어보일 텐데, 나중에 WITH로 가독성 높이는 법 배울 예정!

▶전체 코드

더보기
-- 쿼리 작성하는 목표, 확인할 지표 : Active OR Training인 포켓몬들의 개수
-- 쿼리 계산 방법 : count, left join
-- 데이터의 기간 : 
-- 사용할 테이블 : pokemon, trainer_pokemon
-- JOIN KEY : id, pokemon_id
-- 데이터의 특징 : 
  -- 보유했다의 정의는 status가 'Active', 'Training'인 경우를 의미

SELECT
  -- tp.*, 조회 한 번 해본 뒤
  -- p.id,
  -- p.kor_name,
  kor_name,
  COUNT(tp.id) AS pokemon_cnt
FROM(
      SELECT
        id,
        trainer_id,
        pokemon_id,
        status,
      FROM basic.trainer_pokemon
      WHERE
        status IN("Active","Training")
)AS tp -- 이렇게 row 수를 먼저 줄여두기!⭐
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
GROUP BY kor_name

/* 내 풀이
SELECT
  kor_name,
  COUNT(id) AS pokemon_cnt
FROM(
      SELECT
        tp.id,
        tp.trainer_id,
        tp.pokemon_id,
        tp.status,
        p.kor_name
      FROM basic.trainer_pokemon AS tp
      LEFT JOIN basic.pokemon AS p
      ON tp.pokemon_id = p.id
      WHERE
        status IN("Active","Training")
)
GROUP BY kor_name
*/

 

문제 2. 트레이너가 보유한 포켓몬 중에서 'Grass' 타입은 몇 마리인지 계산해주세요 (단, 편의를 위해 type1 기준으로 계산해주세요)

 

▶내 풀이 과정✅

더보기

1) 데이터 확인

문제 1과 동일

 

2)  WHERE 조건 걸어둔 trainer_pokemon을 기준으로 두고 pokemon을 LEFT JOIN으로 연결

  • tp 전체와, p의 kor_name, type1 이 잘 출력되는지 확인 (이제 여기서 "Grass"의 개수를 세면 됨)

3) COUNT & GROUP BY로 type별 개수 출력 (나머지 select는 주석 처리)

  • 그러면 Grass 타입이 23개임을 확인 가능!

▶강사님 풀이 과정✅

더보기

1) 내 풀이와 비슷한데, GROUP BY 전에 WHERE 조건을 걸어서 아예 Grass 타입 개수만 출력!

  • 엄밀히 말하면 이렇게 출력하는 게 정답!
  • +깨알 팁 : GROUP BY, ORDER BY 할 때 컬럼을 숫자로 지정할 수 있었음!

▶전체 코드

더보기
-- 쿼리 작성하는 목표, 확인할 지표 : 보유 중인 포켓몬 중 type1="Grass" 개수
-- 쿼리 계산 방법 : JOIN, Count + Groupby
-- 데이터의 기간 : 
-- 사용할 테이블 : trainer_pokemon, pokemon
-- JOIN KEY : tp.pokemon_id = p.id
-- 데이터의 특징 : '보유'=status 컬럼으로 확인

SELECT
  -- tp.*,
  -- kor_name,
  type1,
  COUNT(tp.id) AS cnt
FROM(
    SELECT
      id,
      trainer_id,
      pokemon_id,
      status
    FROM basic.trainer_pokemon
    WHERE status IN ('Active', 'Training')
) AS tp
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
WHERE type1 = "Grass"
GROUP BY 1 -- type1 컬럼을 숫자로 지정해봄

/* 내 풀이 과정
SELECT
  -- tp.*,
  -- kor_name,
  type1,
  COUNT(tp.id) AS cnt
FROM(
    SELECT
      id,
      trainer_id,
      pokemon_id,
      status
    FROM basic.trainer_pokemon
    WHERE status IN ('Active', 'Training')
) AS tp
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
GROUP BY type1
*/

 

문제 3. 트레이너의 고향(hometown)과 포켓몬을 포획한 위치(location)를 비교하여, 자신의 고향에서 포켓몬을 포획한 트레이너의 수를 계산해주세요. (*status 상관없이 구해주세요)

 

▶내 풀이 과정❎

더보기

1) 데이터 확인

2) 일단 LEFT JOIN 걸어서, hometown과 location을 한 테이블에서 볼 수 있게 연결

3) WHERE 조건만 추가해서 다시 조회 (location = hometown)

  • 이제 여기서 trainer_id의 개수를 세면 되겠다! (여기서 이미 행 개수 알 수 있긴 함)

4) COUNT로 trainer_id 개수 세니까 43개로 나옴! (나머지 select는 주석 처리) ❎

▶강사님 풀이 과정✅

더보기

1) 원래는 trainer_pokemon을 왼쪽에 두고 푸시지만, 일부러 trainer를 왼쪽에 두고 푸는 걸 보여주심

  • trainer처럼 메타 정보가 들어있는 테이블을 왼쪽에 두면, 아래 그림처럼 갑자기 데이터가 늘어난 것처럼 헷갈릴 수 있음 (ex. 원래 trainer 테이블에는 'Goh'가 1명인데, JOIN한 왼쪽 탭에는 'Goh'가 6명이나 나옴)
  • trainer_pokemon을 왼쪽에 둬도 결과는 똑같긴 한데, 초반 컬럼에 나오는 정보들이 혼동을 줄 수 있다는 말!

2) ⚠️WHERE current_health IS NULL을 추가해서 한 번 조회해봄 → 아무 것도 안 나옴

  • 즉, 모든 트레이너가 1번씩은 포켓몬을 잡아본 적 있다는 뜻 (현업에서 이런 식으로 NULL 있나 체크 잘 해야 함)

3) 그리고 역시 WHERE 조건 location = hometown 걸고, COUNT로 trainer_id 개수 세면 됨!

  • 단, 강사님은 location IS NOT NULL 조건도 걸고 작업하심 (더 안전하게)
  • COUNT에 DISTINCT 붙여줘야 중복 없이 트레이너 개수 출력 가능!! (이걸 놓침) ⇒ 정답은 28개!

▶전체 코드

더보기
-- 쿼리 작성하는 목표, 확인할 지표 : hometown과 location이 동일한 트레이너 수
-- 쿼리 계산 방법 : JOIN -> Where 조건 걸고 Count
-- 데이터의 기간 : 
-- 사용할 테이블 : trainer_pokemon, trainer
-- JOIN KEY : tp.pokemon_id = t.id
-- 데이터의 특징 :

SELECT
  COUNT(trainer_id) AS trainer_cnt,
  COUNT(DISTINCT(trainer_id)) AS trainer_unique
FROM basic.trainer AS t
LEFT JOIN basic.trainer_pokemon AS tp
ON t.id = tp.pokemon_id
WHERE 
  location IS NOT NULL
  AND location = hometown;


--❎내 풀이 과정 --
SELECT
  -- tp.id, COUNT할 때 주석처리
  -- trainer_id,
  -- pokemon_id,
  -- location,
  -- name AS trainer_name,
  -- hometown,
  COUNT(trainer_id) AS trainer_cnt
FROM basic.trainer_pokemon AS tp
LEFT JOIN basic.trainer AS t
ON tp.pokemon_id = t.id
WHERE location = hometown

 

문제 4. Master 등급인 트레이너들은 어떤 타입의 포켓몬을 제일 많이 보유하고 있을까요? (*보유했다의 정의는 1번 문제의 정의와 동일)

 

▶내 풀이 과정✅

더보기

1) 데이터 확인

  • 트레이너 등급은 trainer 테이블에 있네.

 

2) (1번 문제처럼) '보유 중인' 조건으로 일단 trainer_pokemon 테이블 축소하고, trainer 테이블과 JOIN

  • 주요 컬럼만 조회해봄 ➔ 엥 근데 null도 있네? ➔ 알고보니 ON에서 실수했음..
  • 다시 제대로 JOIN함

3) 여기서 WHERE로 Master 등급만 필터링

  • 맨 밑에 WHERE achievement_level = "Master"만 추가하면 됨 = 총 67행 나옴
  • 아 근데 type 보려면 pokemon 테이블도 필요하네;; 추가로 연결하자

4) 지금까지 한 걸 다시 서브쿼리로 감싸고, pokemon과 JOIN

5) 이제 type1으로 그룹화해서 COUNT로 개수 세면 끝

  • 서브쿼리 2번이나 쓰면서 id 중복되는 문제 발생 ➔ 그래서 그냥 t.id 빼버림 (어차피 trainer_id 있으니까)
  • 고친 쿼리에 ORDER BY 추가해서 출력! = water 타입이 14개로 제일 많네!

▶강사님 풀이 과정✅

더보기

1) 데이터 확인

  • achievement_level은 trainer 테이블에 있고, type1은 pokemon 테이블에 있는데, 둘을 연결할 수 없음. 따라서 세 테이블 전부 JOIN이 필요하네!
  • 이런 경우, JOIN에 가장 많이 관여하는 테이블을 기준 테이블로! (ex. trainer_pokemon)

2) tp 테이블에 p 테이블 붙이고, 이어서 바로 t 테이블도 붙임!

  • 일단 SELECT *로 잘 결합됐는지 조회해봄
  • 이랬으면 서브쿼리 2번이나 안 써도 됐는데ㅠ 데이터 확인을 처음에 확실하게 하고 시작해야한다는 것을 느낌

3) 여기서 WHERE로 Master 등급만 필터링

4) 그리고 type1으로 그룹화해서 COUNT하면 끝!

  • ORDER BY로 가장 많은 것부터 출력 =  water 타입이 14개로 제일 많음!

▶전체 코드

더보기
-- Master 등급인 트레이너들은 어떤 타입의 포켓몬을 제일 많이 보유하고 있을까요? (*보유했다의 정의는 1번 문제의 정의와 동일)
-- 쿼리 작성하는 목표, 확인할 지표 : Active or Training인 포켓몬들 + 잡은 트레이너가 Master이어야 함
-- 쿼리 계산 방법 : join
-- 데이터의 기간 : 
-- 사용할 테이블 : trainer_pokemon, trainer, pokemon
-- JOIN KEY : id, trainer_id
-- 데이터의 특징 : 
  -- 보유했다의 정의는 status가 'Active', 'Training'인 경우를 의미
  
SELECT
  type1,
  COUNT(tp.id) AS pokemon_cnt
FROM(
    SELECT
      id,
      trainer_id,
      pokemon_id,
      status,
    FROM basic.trainer_pokemon
    WHERE
      status IN("Active","Training")
) AS tp
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
LEFT JOIN basic.trainer AS t --연달아 2번 JOIN!
ON tp.trainer_id = t.id
WHERE t.achievement_level = "Master"
GROUP BY type1
ORDER BY 2 DESC

-- 내 풀이 과정 --
SELECT
  type1,
  COUNT(DISTINCT(tp_master.id)) AS cnt -- count는 습관적으로 distinct 붙여버리자
FROM(
    SELECT
      tp.*, -- 어차피 이 안에 trainer_id 있으니까 t.id는 빼자!
      t.name AS trainer_name,
      t.achievement_level
    FROM(
          SELECT
            id,
            trainer_id,
            pokemon_id,
            status,
          FROM basic.trainer_pokemon
          WHERE
            status IN("Active","Training")
    )AS tp -- 이렇게 row 수를 먼저 줄여두기!⭐
    LEFT JOIN basic.trainer AS t
    ON tp.trainer_id = t.id
    WHERE achievement_level = "Master"
) AS tp_master
LEFT JOIN basic.pokemon AS p
ON tp_master.pokemon_id = p.id
GROUP BY type1
ORDER BY cnt DESC

 

문제 5. Incheon 출신 트레이너들은 1세대, 2세대 포켓몬을 각각 얼마나 보유하고 있나요?

 

▶내 풀이 과정✅

더보기

1) 데이터 확인

  • 이번에도 세 테이블 전부 필요함! (trainer와 pokemon을 연결해야 하기 때문)

2) 연속 2번 JOIN해서 셋 다 연결하는 것까지는 4번 풀이와 동일

3) 여기서 WHERE로 Incheon 출신만 필터링

4) 그리고 generation으로 그룹화해서 COUNT하면 끝! = 1세대 33마리, 2세대 10마리!


▶강사님 풀이 과정✅

더보기

1) 대부분 동일하고, 아래 세부 내용만 다름

  • JOIN 2번 하실 때 trainer 테이블을 먼저 연결하심 (이건 순서 크게 상관없음)

2) 👨‍🏫데이터가 계속 업데이트 될 경우 주의사항

  • ex) 만약 generation이 3,4, ...계속 나와도 1,2세대만 보고 싶다면? ⇒ WHERE에 generation IN (1,2) 추가해줘야 함!
  • 이런 식으로, 쿼리 수정(리팩토링) 많이 안 해도 되도록 미래의 요구조건까지 생각해보면서 짜면 좋음!

▶전체 코드

더보기
-- Incheon 출신 트레이너들은 1세대, 2세대 포켓몬을 각각 얼마나 보유하고 있나요?
-- 쿼리 작성하는 목표, 확인할 지표 : hometown="Incheon"인 트레이너, generation으로 group by
-- 쿼리 계산 방법 : JOIN으로 셋 다 연결 -> Where 조건 걸고 Count
-- 데이터의 기간 : 
-- 사용할 테이블 : trainer_pokemon, trainer, pokemon
-- JOIN KEY : tp.trainer_id = t.id / tp.pokemon_id = p.id
-- 데이터의 특징 :
  -- 보유했다의 정의는 status가 'Active', 'Training'인 경우를 의미

--✅내 풀이 과정 --
SELECT
  generation,
  COUNT(tp.id) AS pokemon_cnt
FROM(
    SELECT
      id,
      trainer_id,
      pokemon_id,
      status,
    FROM basic.trainer_pokemon
    WHERE
      status IN("Active","Training")
) AS tp
LEFT JOIN basic.pokemon AS p
ON tp.pokemon_id = p.id
LEFT JOIN basic.trainer AS t --연달아 2번 JOIN!
ON tp.trainer_id = t.id
WHERE t.hometown="Incheon"
GROUP BY 1 -- generation 기준으로 그룹화

📌Self-Feedback

  • JOIN Key 설정할 때 테이블 실수 조심하자,,,
  • 쿼리 짜기 전에 필요한(JOIN 해야할) 테이블들이 어떤 건지 확실하게 정의하고 들어가자!

 


🙏References

  • 카일스쿨 님의 인프런 강의 (https://www.inflearn.com/course/%EC%B4%88%EB%B3%B4%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%B9%85%EC%BF%BC%EB%A6%AC-sql-%EC%9E%85%EB%AC%B8/dashboard) 를 듣고 정리한 내용입니다.

 

'SQL > BigQuery' 카테고리의 다른 글

[SQL] 12. 연습문제 풀이  (0) 2025.02.28
[SQL] 11. 쿼리 가독성(WITH), 데이터 결과 검증  (0) 2025.02.23
[SQL] 9. 조건문 (CASE WHEN, IF)  (0) 2025.02.15
[SQL] 8. 다양한 데이터 타입 (날짜 및 시간)  (0) 2025.02.13
[SQL] 7. 다양한 데이터 타입 (CAST, 문자열)  (1) 2025.02.12
  1. 1. JOIN 개념 이해
  2. 포켓몬 데이터 예시
  3. JOIN이 필요한 이유
  4. 2. 다양한 JOIN 함수
  5. 3. JOIN 쿼리 작성 방법
  6. 작성 흐름
  7. 쿼리 문법
  8. 헷갈릴 만한 부분
  9. 4. 연습문제
'SQL/BigQuery' 카테고리의 다른 글
  • [SQL] 12. 연습문제 풀이
  • [SQL] 11. 쿼리 가독성(WITH), 데이터 결과 검증
  • [SQL] 9. 조건문 (CASE WHEN, IF)
  • [SQL] 8. 다양한 데이터 타입 (날짜 및 시간)
simon919
simon919
개인적으로 공부한 내용을 기록하고 나누는 블로그입니다. 데이터 분석, 인공지능에 관한 내용을 주로 다룹니다.
문과생의 AI 생존기개인적으로 공부한 내용을 기록하고 나누는 블로그입니다. 데이터 분석, 인공지능에 관한 내용을 주로 다룹니다.
  • simon919
    문과생의 AI 생존기
    simon919
  • 전체
    오늘
    어제
    • 분류 전체보기 (84)
      • ML & DL (38)
        • 머신러닝 기초 (23)
        • 딥러닝 기초 (6)
        • 데이터마이닝 (9)
      • Data structure & Algorithm (1)
      • SQL (21)
        • BigQuery (13)
        • MySQL (8)
      • Statistics (4)
        • 교육 연구를 위한 통계 (4)
        • Linear Algebra (0)
      • Python (17)
        • Pandas (16)
        • Matplotlib (0)
        • Numpy (0)
        • Web Crawling (1)
      • Projects (0)
      • Etc. (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 글자가 깨지면 새로고침 해주세요 :)
  • 인기 글

  • 태그

    google cloud
    Xai
    티스토리 스킨
    해커랭크
    SQL
    SQL코딩테스트
    HELLO 스킨
    MaxPooling2D
    SQL문제풀이
    데이터마이닝
    kmooc
    Functional API
    블로그 스킨
    최우수혼공족
    혼공학습단
    ml기초
    agglomerative
    BigQuery
    Conv2d
    리트코드
    Bayesian Optimization
    통계학 기초
    pytorch
    교육통계
    혼공머신
    kmeans
    silhouette index
    특성맵 시각화
    mysql
    pandas
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
simon919
[SQL] 10. 데이터 연결 (JOIN)

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.