개발자의 끄적끄적

[MySQL] 8장 유니온(UNION), 서브 쿼리 [펌] 본문

개발/sql

[MySQL] 8장 유니온(UNION), 서브 쿼리 [펌]

효벨 2020. 3. 23. 02:00
728x90
반응형

[MySQL] 8장 유니온(UNION), 서브 쿼리 [펌]

 

 

CREATE TABLE girl_group
(
_id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL,
debut DATE NOT NULL,
hit_song_id INT
);
 
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('원더걸스', '2007-09-12', 101);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('소녀시대', '2009-06-03', 102);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('카라', '2009-07-30', 103);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('브라운아이드걸스', '2008-01-17', 104);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('다비치', '2009-02-27', 105);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('2NE1', '2009-07-08', 107);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('f(x)', '2011-04-20', 109);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('시크릿', '2011-01-06', 110);
INSERT INTO girl_group (name, debut, hit_song_id)
VALUES ('레인보우', '2010-08-12', 111);
INSERT INTO girl_group (name, debut)
VALUES ('에프터 스쿨', '2009-11-25');
INSERT INTO girl_group (name, debut)
VALUES ('포미닛', '2009-08-28');
 
CREATE TABLE professor
(
_id INT AUTO_INCREMENT,
name VARCHAR(32) NOT NULL,
belong VARCHAR(12) DEFAULT 'FOO',
phone VARCHAR(12),
PRIMARY KEY(_id)
) ENGINE=INNODB;
 
INSERT INTO professor
(name, belong, phone)
VALUES('유재석', 'IDE','01112345678');
 
INSERT INTO professor
(name, belong, phone)
VALUES('황영조', 'MSE', '01121342443');
 
INSERT INTO professor
(name, belong, phone)
VALUES('케이멀', 'ESE', '01123424343');
 
INSERT INTO professor
(_id, name, belong, phone)
VALUES(256, '호날두', 'IME', '01134343222');
 
INSERT INTO professor
(name, belong, phone)
VALUES( '리오넬', 'IDE', '01123432432');
SELECT _id, belong, phone FROM professor;
SELECT * FROM professor;

view rawmysql_41.sql hosted with ❤ by GitHub

 

 

1. 유니온 (UNION)

 

지금까지 테이블의 데이터는 아래와 같다. 

 

 

두 테이블에서 이름만 꺼내서 아래와 같이 하나의 테이블로 나타내고 싶다.

 

 

 

SELECT name FROM professor
UNION
SELECT name FROM girl_group;

view rawmysql_42.sql hosted with ❤ by GitHub

 

UNION은 몇개 라도 계속해서 연결할 수 있다.

 

유니온의 규칙

 

  1. 하나의 ORDER BY만 사용할 수 있다.
  2. 각 SELECT의 열수, 표현식가 같아야 한다.
  3. SELECT 문들 끼리 순서는 상관없다.
  4. 유니온을 한 결과가 중복되면 하나만 나온다. (DEFAULT)
  5. 열의 타입은 같거나 반환 가능한 형태여야 한다.
  6. 중복값을 나타내고 싶다면 UNION ALL

 

 

2. 서브 쿼리

 

서브쿼리는 6장 테이블 쪼개기를 하면서 잠깐 등장한 적이 있다. 서브 쿼리는 JOIN으로 할 수 있는 기능과 유사한 기능을 제공한다. 

이번 시간에는 서브 쿼리가 어떤 경우에 유용하게 사용할 수 있을지에 대해 알아보자.

 

우선 저번 시간에 사용했던 girl_group 테이블과 song 테이블을 사용한다. 이 테이블이 없다면 링크를 통해 테이블을 추가하도록 하자.

https://gist.github.com/tmmoond8/fc8ba6f4d046aec117968bb80e97a294

 

SELECT *
FROM girl_group
WHERE hit_song_id = (SELECT _id
FROM song
WHERE lyrics LIKE '%Give%'
);
 
SELECT *
FROM girl_group
WHERE hit_song_id IN (SELECT _id
FROM song
WHERE lyrics LIKE '%e%'
);
 
SELECT gg.name, gg.debut, s.title
FROM girl_group AS gg
JOIN song AS s
ON gg.hit_song_id = s._id
WHERE s.lyrics LIKE '%e%';

view rawmysql_43.sql hosted with ❤ by GitHub

 

 

첫 번째 쿼리 결과

 

 

 

3 ~6 : (SELECT 부터 뒷 부분이 서브 쿼리다. 결과는 hit_song_id과 동일한 값인지 비교하게 된다. 이 때  서브 쿼리의 결과는 한 개 보다 크다면 오류가 발생한다.

여러 값을 비교하고 싶다면 두 번째 쿼리를 사용하면 된다. 

 

두 번째 쿼리 결과

 

 

 

세 번째 쿼리 결과

 

 

 

데이터를 유사하게 가져오지만, title 열을 song 테이블에 있는 열이다. 

서브 쿼리의 위치는 다양하다. 위와 같이 사용하면 쿼리 결과에 song의 열은 포함할 수 없다. 위 join과 같은 결과를 얻기 위해선 아래와 같이 서브쿼리를 사용

하면 된다.

SELECT gg.name, gg.debut,
(SELECT title
FROM song
WHERE title IS NOT NULL
AND lyrics LIKE '%e%'
AND gg.hit_song_id = _id
) AS hitsong
FROM girl_group AS gg;

view rawmysql_44.sql hosted with ❤ by GitHub

 

지금 부터 서브 쿼리의 유용성에 대해 말해보겠다. 사실, JOIN이 서브 쿼리에 비해 속도 면에서는 더 좋은 것은 분명하다. 그러나 JOIN은 그 결과를

SELECT 하는 것만 가능하다는 단점이 있다. 그렇다, 서브 쿼리는 SELECT, INSERT, UPDATE, DELETE 모두 가능하다.

 

DELETE FROM girl_group
WHERE hit_song_id IN (SELECT _id
FROM song
WHERE lyrics LIKE '%e%'
);

view rawmysql_45.sql hosted with ❤ by GitHub

 

위 쿼리를 싱행하면 가사에 'e' 문자를 포함 하는 노래를 히트곡으로 하는 걸그룹이 삭제가 된다.

 

 

 

이번 시간에는 유니온과 서브 쿼리에 대해 배웠다. 이제 실무에서 사용할 수 있는 다양한 쿼리를 작성할 수 있는 베이스를 갖췄다. ORDER BY, GROUP BY, 서브 쿼리, 조인, 내부 함수 등을 잘 적용하면 원하는 결과를 얻어 낼 수 있는 쿼리를 작성할 수 있을 것이라 믿는다. 



출처: https://futurists.tistory.com/18 [미래학자]

반응형
Comments