SQL - [UNION, JOIN]

솔비·2024년 1월 16일
0

UNION 실습환경구축


  • 테이블 생성

    mysql> create table test1
        -> ( no int );
    Query OK, 0 rows affected (0.09 sec)
    
    mysql> create table test2
        -> ( no int );
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> show tables;
    +--------------------+
    | Tables_in_zerobase |
    +--------------------+
    | celeb              |
    | test1              |
    | test2              |
    +--------------------+
    3 rows in set (0.00 sec)
  • 데이터 입력

    insert into test1 values (1);
    Query OK, 1 row affected (0.02 sec)
    
    mysql> insert into test1 values (2);
    Query OK, 1 row affected (0.02 sec)
    
    mysql> insert into test1 values (3);
    Query OK, 1 row affected (0.01 sec)
    
    select * from test1;
    +------+
    | no   |
    +------+
    |    1 |
    |    2 |
    |    3 |
    +------+
    3 rows in set (0.00 sec)
    
    insert into test2 values (5);
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  insert into test2 values (6);
    Query OK, 1 row affected (0.02 sec)
    
    mysql> insert into test2 values (3);
    Query OK, 1 row affected (0.02 sec)
    
    mysql> select * from test2;
    +------+
    | no   |
    +------+
    |    5 |
    |    6 |
    |    3 |
    +------+
    3 rows in set (0.00 sec)

    ➡️ TEST1 테이블의 no 컬럼에는 value 123을
    TEST2 테이블의 no 컬럼에는 value 563을 입력




UNION


🧷 UNION : 중복된 값을 제거

SELECT column1, column2, ... FROM tableA
UNION
SELECT column1, column2, ... FROM tableB

🧷 UNION ALL : 중복된 값도 모두

SELECT column1, column2, ... FROM tableA
UNION ALL
SELECT column1, column2, ... FROM tableB

단, 두가지 모두 가져오는 컬럼의 개수가 같아야한다.

  • TEST1 테이블과 TEST2 테이블 UNION

    mysql> select * from test1
       -> union
       -> select * from test2;
    +------+
    | no   |
    +------+
    |    1 |
    |    2 |
    |    3 |
    |    5 |
    |    6 |
    +------+
    5 rows in set (0.01 sec)
  • TEST1 테이블과 TEST2 테이블 UNION ALL

    mysql> SELECT * FROM TEST1
       -> UNION ALL
       -> SELECT * FROM TEST2;
    +------+
    | no   |
    +------+
    |    1 |
    |    2 |
    |    3 |
    |    5 |
    |    6 |
    |    3 |
    +------+
    6 rows in set (0.00 sec)

📌 가수가 직업인 연예인의 이름, 직업을 검색하는 쿼리와,
1980년대에 태어난 연예인의 이름, 생년월일, 나이를 검색하는 쿼리를 UNION으로 실행

mysql>SELECT name, job_title FROM celeb WHERE job_title LIKE '%가수%'
    -> UNION
    -> SELECT name, birthday, age FROM CELEB WHERE birthday BETWEEN 19800101 AND 19891231;
ERROR 1222 (21000): The used SELECT statements have a different number of columns

➡️ ERROR | 가져오는 컬럼의 수가 다르기 때문


📌 직업이 가수인 (가수를 포함하는) 데이터를 검색하는 쿼리와
직업이 텔런트인 (텔런트를 포함하는) 데이터를 검색하는 쿼리를
중복을 제거하여 합쳐서 실행하세요

mysql> SELECT * FROM celeb WHERE job_title LIKE '%가수%'
    -> UNION
    -> SELECT * FROM celeb WHERE job_title LIKE '%탤런트%';
+----+-----------+------------+------+------+-------------------------+--------------------------+
| ID | NAME      | BIRTHDAY   | AGE  | SEX  | JOB_TITLE               | AGENCY
    |
+----+-----------+------------+------+------+-------------------------+--------------------------+
|  1 | 아이유    | 1993-05-16 |   29 | F    | 가수, 탤런트            | EDAM엔터테이먼트         |
|  2 | 이미주    | 1994-09-23 |   28 | F    | 가수                    | 울림엔터테이먼트         |
|  7 | 이수현    | 1999-05-04 |   23 | F    | 가수                    | YG엔터테이먼트           |
|  3 | 송강      | 1994-04-23 |   28 | M    | 탤런트                  | 나무엑터스
    |
|  4 | 강동원    | 1981-01-18 |   41 | M    | 영화배우, 탤런트        | YG엔터테이먼트           |
+----+-----------+------------+------+------+-------------------------+--------------------------+
5 rows in set (0.00 sec)

📌 성이 이씨인 데이터를 검색하는 쿼리와 1970년대생을 검색하는 쿼리를 중복을 포함하여 합쳐서 실행하세요.

mysql> SELECT * FROM celeb WHERE name LIKE '이%'
    -> UNION ALL
    -> SELECT * FROM celeb WHERE birthday BETWEEN 19700101 AND 19791231;
+----+-----------+------------+------+------+----------------------+--------------------------+
| ID | NAME      | BIRTHDAY   | AGE  | SEX  | JOB_TITLE            | AGENCY
 |
+----+-----------+------------+------+------+----------------------+--------------------------+
|  2 | 이미주    | 1994-09-23 |   28 | F    | 가수                 | 울림엔터테이먼트         |
|  7 | 이수현    | 1999-05-04 |   23 | F    | 가수                 | YG엔터테이먼트
 |
|  5 | 유재석    | 1972-08-14 |   50 | M    | MC, 개그맨           | 안테나
 |
|  6 | 차승원    | 1970-06-07 |   48 | M    | 영화배우, 모델       | YG엔터테이먼트
 |
+----+-----------+------------+------+------+----------------------+--------------------------+
4 rows in set (0.00 sec)



JOIN 실습환경구축


  • snl_show TABLE 생성

    mysql> CREATE TABLE snl_show
        -> (
        -> ID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
        -> SEASON int NOT NULL,
        -> EPISODE int NOT NULL,
        -> BROADCAST_DATE date,
        -> HOST varchar(32) NOT NULL
        -> );
    Query OK, 0 rows affected (0.06 sec)
  • 데이터입력

     INSERT INTO snl_show VALUES(1,8,7,'2020-09-05','강동원');
    Query OK, 1 row affected (0.01 sec)
    
    mysql>  INSERT INTO snl_show VALUES(2,8,8,'2020-09-12','유재석');
    Query OK, 1 row affected (0.01 sec)
    
    mysql>  INSERT INTO snl_show VALUES(3,8,9,'2020-09-19','차승원');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(4,8,10,'2020-09-26','이수현');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(5,9,1,'2021-09-04','이병헌');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(6,9,2,'2021-09-11','하지원');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(7,9,3,'2021-09-18','제시');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(8,9,4,'2021-09-25','조정석');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(9,9,5,'2021-10-02','조여정');
    Query OK, 1 row affected (0.02 sec)
    
    mysql>  INSERT INTO snl_show VALUES(10,9,6,'2021-10-09','옥주현');
    Query OK, 1 row affected (0.02 sec)
    
    mysql> SELECT * FROM snl_show;
    +----+--------+---------+----------------+-----------+
    | ID | SEASON | EPISODE | BROADCAST_DATE | HOST      |
    +----+--------+---------+----------------+-----------+
    |  1 |      8 |       7 | 2020-09-05     | 강동원    |
    |  2 |      8 |       8 | 2020-09-12     | 유재석    |
    |  3 |      8 |       9 | 2020-09-19     | 차승원    |
    |  4 |      8 |      10 | 2020-09-26     | 이수현    |
    |  5 |      9 |       1 | 2021-09-04     | 이병헌    |
    |  6 |      9 |       2 | 2021-09-11     | 하지원    |
    |  7 |      9 |       3 | 2021-09-18     | 제시      |
    |  8 |      9 |       4 | 2021-09-25     | 조정석    |
    |  9 |      9 |       5 | 2021-10-02     | 조여정    |
    | 10 |      9 |       6 | 2021-10-09     | 옥주현    |
    +----+--------+---------+----------------+-----------+
    10 rows in set (0.00 sec)



JOIN



  • 실습테이블 INNER값



1. INNER JOIN


🧷 INNER JOIN 사용법
SELECT column1, column2, ...
FROM tableA
INNER JOIN tableB
ON tableA.column = tableB.column
WHERE condition;

📌 예제

mysql> SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
    -> FROM celeb
    -> INNER JOIN snl_show
    -> ON celeb.name = snl_show.host;
+----+-----------+----+-----------+
| id | name      | id | host      |
+----+-----------+----+-----------+
|  4 | 강동원    |  1 | 강동원    |
|  5 | 유재석    |  2 | 유재석    |
|  6 | 차승원    |  3 | 차승원    |
|  7 | 이수현    |  4 | 이수현    |
+----+-----------+----+-----------+
4 rows in set (0.00 sec)



2. LEFT JOIN


🧷 LEFT JOIN 사용법
SELECT column1, column2, ...
FROM tableA
LEFT JOIN tableB
ON tableA.column = tableB.column
WHERE condition;

📌 예제

mysql> SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
    -> FROM celeb
    -> LEFT JOIN snl_show
    -> ON celeb.name = snl_show.host;
+----+-----------+------+-----------+
| id | name      | id   | host      |
+----+-----------+------+-----------+
|  1 | 아이유    | NULL | NULL      |
|  2 | 이미주    | NULL | NULL      |
|  3 | 송강      | NULL | NULL      |
|  4 | 강동원    |    1 | 강동원    |
|  5 | 유재석    |    2 | 유재석    |
|  6 | 차승원    |    3 | 차승원    |
|  7 | 이수현    |    4 | 이수현    |
+----+-----------+------+-----------+
7 rows in set (0.00 sec)



3. RIGHT JOIN


🧷 RIGHT JOIN 사용법
SELECT column1, column2, ...
FROM tableA
RIGHT JOIN tableB
ON tableA.column = tableB.column
WHERE condition;

📌 예제

mysql> SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
  -> FROM celeb
  -> RIGHT JOIN snl_show
  -> ON celeb.name = snl_show.host;
+------+-----------+----+-----------+
| id   | name      | id | host      |
+------+-----------+----+-----------+
|    4 | 강동원    |  1 | 강동원    |
|    5 | 유재석    |  2 | 유재석    |
|    6 | 차승원    |  3 | 차승원    |
|    7 | 이수현    |  4 | 이수현    |
| NULL | NULL      |  5 | 이병헌    |
| NULL | NULL      |  6 | 하지원    |
| NULL | NULL      |  7 | 제시      |
| NULL | NULL      |  8 | 조정석    |
| NULL | NULL      |  9 | 조여정    |
| NULL | NULL      | 10 | 옥주현    |
+------+-----------+----+-----------+
10 rows in set (0.00 sec)



4. FULL OUTER JOIN


🧷 FULL OUTER JOIN 사용법
SELECT column1, column2, ...
FROM tableA
FULL OUTER JOIN tableB
ON tableA.column = tableB.column
WHERE condition;
단, Mysql에서는 지원하지 않으므로 LEFT JOIN 과 RIGHR JOIN을 UNION 할것

📌 예제

mysql> SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
  -> FROM celeb
  -> LEFT JOIN snl_show
  -> ON celeb.name = snl_show.host
  -> UNION
  -> SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
  -> FROM celeb
  -> RIGHT JOIN snl_show
  -> ON celeb.name = snl_show.host;
+------+-----------+------+-----------+
| id   | name      | id   | host      |
+------+-----------+------+-----------+
|    1 | 아이유    | NULL | NULL      |
|    2 | 이미주    | NULL | NULL      |
|    3 | 송강      | NULL | NULL      |
|    4 | 강동원    |    1 | 강동원    |
|    5 | 유재석    |    2 | 유재석    |
|    6 | 차승원    |    3 | 차승원    |
|    7 | 이수현    |    4 | 이수현    |
| NULL | NULL      |    5 | 이병헌    |
| NULL | NULL      |    6 | 하지원    |
| NULL | NULL      |    7 | 제시      |
| NULL | NULL      |    8 | 조정석    |
| NULL | NULL      |    9 | 조여정    |
| NULL | NULL      |   10 | 옥주현    |
+------+-----------+------+-----------+
13 rows in set (0.00 sec)



5. SELF JOIN 🌟🌟


🧷 SELF JOIN 사용법
SELECT column1, column2, ...
FROM tableA, tableB
WHERE condition;
결과는 INNER JOIN | WHERE절에서 =를 명시할것.

📌 예제

mysql> SELECT celeb.id, celeb.name, snl_show.id, snl_show.host
  -> FROM celeb, snl_show
  -> WHERE celeb.name = snl_show.host;
+----+-----------+----+-----------+
| id | name      | id | host      |
+----+-----------+----+-----------+
|  4 | 강동원    |  1 | 강동원    |
|  5 | 유재석    |  2 | 유재석    |
|  6 | 차승원    |  3 | 차승원    |
|  7 | 이수현    |  4 | 이수현    |
+----+-----------+----+-----------+
4 rows in set (0.00 sec)

📌 celeb 테이블의 연예인 중, snl_show 에 host 로 출연했고 소속사가 안테나인 사람의 이름과 직업을 검색

mysql> SELECT celeb.name, celeb.job_title
    -> FROM celeb, snl_show
    -> where celeb.name = snl_show.host
    -> AND celeb.agency = '안테나';
+-----------+---------------+
| name      | job_title     |
+-----------+---------------+
| 유재석    | MC, 개그맨    |
+-----------+---------------+
1 row in set (0.00 sec)

📌 celeb 테이블의 연예인 중 snl_show 에 host 로 출연했고,
영화배우는 아니면서 YG 엔터테이먼트 소속이거나 40세 이상이면서 YG 엔터테이먼트 소속이 아닌
연예인의 이름과 나이, 직업, 소속사, 시즌, 에피소드 정보를 검색

mysql> SELECT celeb.name,celeb.job_title,celeb.agency,snl_show.season,snl_show.episode
    -> FROM celeb, snl_show
    -> WHERE celeb.name = snl_show.host
    -> AND ((not celeb.job_title like '%영화배우%' and agency = 'YG엔터테이먼트')
    ->  OR (age >= 40 and not agency = 'YG엔터테이먼트'));
+-----------+---------------+----------------------+--------+---------+
| name      | job_title     | agency               | season | episode |
+-----------+---------------+----------------------+--------+---------+
| 유재석    | MC, 개그맨    | 안테나               |      8 |       8 |
| 이수현    | 가수          | YG엔터테이먼트       |      8 |      10 |
+-----------+---------------+----------------------+--------+---------+
2 rows in set (0.00 sec)

🧷 동일한 컬럼명이 있을 경우에만 테이블명을 붙여줘도된다.

📌 snl_show 에 출연한 연예인의 snl_show 아이디, 시즌, 에피소드, 이름, 직업 정보를 검색
➡️ 동일 컬럼명은 아이디이므로, 아이디에만 테이블명을 명시해도 됨

mysql> SELECT snl_show.id, season,episode, name, job_title
    -> FROM snl_show, celeb
    -> WHERE name = host;
+----+--------+---------+-----------+-------------------------+
| id | season | episode | name      | job_title               |
+----+--------+---------+-----------+-------------------------+
|  1 |      8 |       7 | 강동원    | 영화배우, 탤런트        |
|  2 |      8 |       8 | 유재석    | MC, 개그맨              |
|  3 |      8 |       9 | 차승원    | 영화배우, 모델          |
|  4 |      8 |      10 | 이수현    | 가수                    |
+----+--------+---------+-----------+-------------------------+
4 rows in set (0.00 sec)

❗ snl_show 에 출연한 celeb 중, 에피소드 7, 9, 10 중에 출연했거나 소속사가 YG로 시작하고 / 뒤에 6글자로 끝나는 사람 중 작년 9월 15일 이후에 출연했던 사람을 검색

mysql> SELECT name, season, episode, broadcast_date, agency
    -> FROM snl_show, celeb
    -> WHERE name = host
    -> AND (episode in (7,9,10) or agency = 'YG______')
    -> AND broadcast_date > '2020-09-15';
+-----------+--------+---------+----------------+----------------------+
| name      | season | episode | broadcast_date | agency               |
+-----------+--------+---------+----------------+----------------------+
| 차승원    |      8 |       9 | 2020-09-19     | YG엔터테이먼트       |
| 이수현    |      8 |      10 | 2020-09-26     | YG엔터테이먼트       |
+-----------+--------+---------+----------------+----------------------+
2 rows in set (0.00 sec)

😅 문단을 끊는게 살짝 애매하다..


❗ snl_show 에 출연한 celeb 테이블의 연예인 중, 영화배우나 텔런트가 아닌 연예인의
아이디, 이름, 직업, 시즌, 에피소드 정보를 검색하세요

SELECT celeb.id, name, job_title, season, episode
    -> FROM celeb, snl_show
    -> WHERE name = host
    -> AND NOT job_title like '%영화배우%' and NOT job_title like '%탤런트%';
+----+-----------+---------------+--------+---------+
| id | name      | job_title     | season | episode |
+----+-----------+---------------+--------+---------+
|  5 | 유재석    | MC, 개그맨    |      8 |       8 |
|  7 | 이수현    | 가수          |      8 |      10 |
+----+-----------+---------------+--------+---------+
2 rows in set (0.00 sec)
mysql> SELECT celeb.id, name, job_title, season, episode
    -> FROM celeb, snl_show
    -> WHERE name = host
    -> AND NOT (job_title like '%영화배우%' OR job_title like '%탤런트%');
+----+-----------+---------------+--------+---------+
| id | name      | job_title     | season | episode |
+----+-----------+---------------+--------+---------+
|  5 | 유재석    | MC, 개그맨    |      8 |       8 |
|  7 | 이수현    | 가수          |      8 |      10 |
+----+-----------+---------------+--------+---------+
2 rows in set (0.00 sec)

🧷 위처럼 NOT 뒤 괄호에 OR이 들어갈경우
내용을 풀어쓰면 or -> and가 된다.
ex) not(condition or condition)
= not condition and not condtion


📌 snl_show 에 출연한 celeb 중, 작년 9월 15일 이후에 출연했거나
소속사 이름이 ‘엔터테이먼트’ 로 끝나지 않으면서 영화배우나 개그맨이 아닌 연예인의
celeb 아이디, 이름, 직업, 소속사를 검색하세요

mysql> SELECT celeb.id, name, job_title, agency
    -> FROM snl_show, celeb
    -> WHERE name = host
    -> AND (broadcast_date > 20200915 or not agency like '%엔터테이먼트')
    -> AND NOT (job_title like '%영화배우%' OR job_title like '%개그맨%');
+----+-----------+-----------+----------------------+
| id | name      | job_title | agency               |
+----+-----------+-----------+----------------------+
|  7 | 이수현    | 가수      | YG엔터테이먼트       |
+----+-----------+-----------+----------------------+
1 row in set (0.00 sec)

Daily Study Note
profile
Study Log

0개의 댓글