SQL(5)(inner join, outer join, left join, right join, full outer join)

INNER JOIN

inner join은 on명령문에 명시된 조인 조건을 충족하지 않는 두 테이블의 행을 제거한다.









1
2
3
4
5
SELECT players.*,
       teams.*
  FROM benn.college_football_players players
  JOIN benn.college_football_teams teams
    ON teams.school_name = players.school_name
cs








1
2
3
4
5
SELECT players.school_name AS players_school_name,
       teams.school_name AS teams_school_name
  FROM benn.college_football_players players
  JOIN benn.college_football_teams teams
    ON teams.school_name = players.school_name
cs









연습문제

"FBS(Division IA Teams)"부서에 있는 학교의 선수 이름, 학교 이름 및 회의를 표시하는 쿼리를 작성

1
2
3
4
5
6
7
SELECT players.player_name,
       players.school_name,
       teams.conference
  FROM benn.college_football_players players
  JOIN benn.college_football_teams teams
    ON teams.school_name = players.school_name
 WHERE teams.division = 'FBS (Division I-A Teams)'
cs










OUTER JOIN

outer join에서는 하나 또는 두 테이블 모두에서 일치하지 않는 행이 봔환 될 수 있다.

몇 가지 유형의 외부 조인이 있다. 자세한 내용은 아래에서 다룰 예정이다.







LEFT JOIN










1
2
3
4
5
6
7
SELECT companies.permalink AS companies_permalink,
       companies.name AS companies_name,
       acquisitions.company_permalink AS acquisitions_permalink,
       acquisitions.acquired_at AS acquired_date
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
cs








연습문제

tutorial.crunchbase_acquisitions테이블과 tutorial.crunchbase_companies테이블간에 내부조인을 수행하는 쿼리를 작성, 개별 행을 나열하는 대신 각 테이블에서 Null이 아닌 행의 수를 계산

1
2
3
4
5
SELECT COUNT(companies.permalink) AS companies_rowcount,
       COUNT(acquisitions.company_permalink) AS acquisitions_rowcount
  FROM tutorial.crunchbase_companies companies
  JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
cs




위의 쿼리를 LEFT JOIN으로 작성

1
2
3
4
5
SELECT COUNT(companies.permalink) AS companies_rowcount,
       COUNT(acquisitions.company_permalink) AS acquisitions_rowcount
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
cs




주별로 고유한 회사와 인수한 고유회사의 수를 계산. 상태 데이터가 없는 결과를 포함하지 말고 인수한 회사 수를 기준으로 높은 순서에서 낮은 순서로 정렬

1
2
3
4
5
6
7
8
9
SELECT companies.state_code,
       COUNT(DISTINCT companies.permalink) AS unique_companies,
       COUNT(DISTINCT acquisitions.company_permalink) AS unique_companies_acquired
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
 WHERE companies.state_code IS NOT NULL
 GROUP BY companies.state_code
 ORDER BY unique_companies_acquired DESC
cs









RIGHT JOIN








right join은 두 테이블의 이름을 간단히 전환하여 left join과 동일한 결과를 반환하기 때문에 거의 사용되지 않는다. 예는 다음과 같다.

1
2
3
4
5
6
7
SELECT companies.permalink AS companies_permalink,
       companies.name AS companies_name,
       acquisitions.company_permalink AS acquisitions_permalink,
       acquisitions.acquired_at AS acquired_date
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
cs

1
2
3
4
5
6
7
SELECT companies.permalink AS companies_permalink,
       companies.name AS companies_name,
       acquisitions.company_permalink AS acquisitions_permalink,
       acquisitions.acquired_at AS acquired_date
  FROM tutorial.crunchbase_acquisitions acquisitions
 RIGHT JOIN tutorial.crunchbase_companies companies
    ON companies.permalink = acquisitions.company_permalink
cs








연습문제

총계 및 인수 회사를 주별로 세었지만 left join대신 right join을 사용하여 이전 질의를 다시 작성. 정확히 같은 결과를 반환해야 한다.

1
2
3
4
5
6
7
8
9
SELECT companies.state_code,
       COUNT(DISTINCT companies.permalink) AS unique_companies,
       COUNT(DISTINCT acquisitions.company_permalink) AS acquired_companies
  FROM tutorial.crunchbase_acquisitions acquisitions
 RIGHT JOIN tutorial.crunchbase_companies companies
    ON companies.permalink = acquisitions.company_permalink
 WHERE companies.state_code IS NOT NULL
 GROUP BY companies.state_code
 ORDER BY acquired_companies DESC
cs










JOINS USING WHERE OR ON

ON

join전에 하나 또는 둘의 테이블을 필터링 할 수 있다.

1
2
3
4
5
6
7
8
9
SELECT companies.permalink AS companies_permalink,
       companies.name AS companies_name,
       acquisitions.company_permalink AS acquisitions_permalink,
       acquisitions.acquired_at AS acquired_date
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
   AND acquisitions.company_permalink != '/company/1000memories'
 ORDER BY companies_permalink
cs








WHERE

1
2
3
4
5
6
7
8
9
10
SELECT companies.permalink AS companies_permalink,
       companies.name AS companies_name,
       acquisitions.company_permalink AS acquisitions_permalink,
       acquisitions.acquired_at AS acquired_date
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
 WHERE acquisitions.company_permalink != '/company/1000memories'
    OR acquisitions.company_permalink IS NULL
 ORDER BY companies_permalink
cs








where절의 필터링은 null값도 필터링 할 수 있으므로 null을 포함하도록 추가 행을 추가했다.

연습문제

회사 이름, 상태 및 해당 회사의 고유 투자자 수를 표시하는 쿼리를 작성. 투자자 수를 기준으로 가장 적은 순서로 정렬. 뉴욕주에 있는 회사로만 제한.

1
2
3
4
5
6
7
8
9
SELECT companies.name AS company_name,
       companies.status,
       COUNT(DISTINCT investments.investor_name) AS unqiue_investors
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_investments investments
    ON companies.permalink = investments.company_permalink
 WHERE companies.state_code = 'NY'
 GROUP BY company_name,companies.status
 ORDER BY unqiue_investors DESC
cs











투자한 회사 수에 따라 투자자를 나열하는 쿼리를 작성. 투자자가 없는 회사의 행을 포함하고 대부분의 회사에서 가장 적은 순서.

1
2
3
4
5
6
7
8
SELECT CASE WHEN investments.investor_name IS NULL THEN 'No Investors'
            ELSE investments.investor_name END AS investor,
       COUNT(DISTINCT companies.permalink) AS companies_invested_in
  FROM tutorial.crunchbase_companies companies
  LEFT JOIN tutorial.crunchbase_investments investments
    ON companies.permalink = investments.company_permalink
 GROUP BY investor
 ORDER BY companies_invested_in DESC
cs











FULL OUTER JOIN

두 테이블 모두에서 일치하지 않는 행을 반환한다. 두 테이블 간의 겹침 정도를 이해하기 위해 집계와 함께 일반적으로 사용된다.

1
2
3
4
5
6
7
8
9
SELECT COUNT(CASE WHEN companies.permalink IS NOT NULL AND acquisitions.company_permalink IS NULL
                  THEN companies.permalink ELSE NULL END) AS companies_only,
       COUNT(CASE WHEN companies.permalink IS NOT NULL AND acquisitions.company_permalink IS NOT NULL
                  THEN companies.permalink ELSE NULL END) AS both_tables,
       COUNT(CASE WHEN companies.permalink IS NULL AND acquisitions.company_permalink IS NOT NULL
                  THEN acquisitions.company_permalink ELSE NULL END) AS acquisitions_only
  FROM tutorial.crunchbase_companies companies
  FULL JOIN tutorial.crunchbase_acquisitions acquisitions
    ON companies.permalink = acquisitions.company_permalink
cs




연습문제

tutorial.crunchbase_companies 및 tutorial.crunchbase_investments_part1을 사용. 위의 예와 같이 일치/ 불일치 하는 행 수를 계산

1
2
3
4
5
6
7
8
9
SELECT COUNT(CASE WHEN companies.permalink IS NOT NULL AND investments.company_permalink IS NULL
                  THEN companies.permalink ELSE NULL END) AS companies_only,
       COUNT(CASE WHEN companies.permalink IS NOT NULL AND investments.company_permalink IS NOT NULL
                  THEN companies.permalink ELSE NULL END) AS both_tables,
       ㅜCOUNT(CASE WHEN companies.permalink IS NULL AND investments.company_permalink IS NOT NULL
                  THEN investments.company_permalink ELSE NULL END) AS investments_only
  FROM tutorial.crunchbase_companies companies
  FULL JOIN tutorial.crunchbase_investments_part1 investments
    ON companies.permalink = investments.company_permalink
cs





댓글

이 블로그의 인기 게시물

SQL(9)(performance tuning queries, pivoting data)

데이터 크롤링(3주차)

SQL(8)(writing subqueries, window functions)