본문 바로가기

Structured Query Language/MY_SQL_basic

SQL_Basic_09_Day 10. 조건에 조건 더하기

Day 10. 조건에 조건 더하기


1. 조건에 조건 더하기


서브쿼리

 

 

 

서브쿼리 특징

 

하나의 쿼리 내 포함된 또 하나의 쿼리를 의미.
서브쿼리는 반드시 괄호 안에 있어야 한다.
SELECT, FROM, WHERE, HAVING, ORDER BY 절에 사용가능.
INSERT, UPDATE, DELETE 문에도 사용가능.
서브쿼리에는 ; (세미콜론)을 붙이지 않아도 된다.

 

 

2. SELECT절의 서브쿼리


스칼라 서브쿼리라고도 한다.
SELECT절의 서브쿼리는 반드시 결과값이 하나의 값이어야 한다.

 

SELECT절의 서브쿼리 문법

 

SELECT [컬럼이름],
( SELECT [컬럼이름]
FROM[테이블이름]
WHERE조건식)
FROM[테이블이름]
WHERE조건식;

 

SELECT절의 서브쿼리 예제

 

 

 

3. FROM절의 서브쿼리


인라인뷰 서브쿼리라고도 한다.
FROM절의 서브쿼리는 반드시 결과값이 하나의 테이블이여야 한다.
서브쿼리로 만든 테이블은 반드시 별명을 가져야 한다.

 

FROM절의 서브쿼리 문법

 

SELECT [컬럼이름]
FROM( SELECT [컬럼이름]
        FROM[테이블이름]
        WHERE조건식) AS [테이블별명]
WHERE조건식;

 

 

FROM절의 서브쿼리 예제

 

 

 

 

4. WHERE절의 서브쿼리


중첩 서브쿼리라고도 한다.
WHERE절의 서브쿼리는 반드시 결과값이 하나의 컬럼이어야합니다. (EXISTS 제외)
하나의 컬럼에는 여러개의 값이 존재할 수 있다.
연산자와 함께 사용.

보통 WHERE [컬럼이름] [연산자] [서브쿼리] 형식으로 사용한다.

 

WHERE절의 서브쿼리 문법

 

SELECT [컬럼이름]
FROM[테이블이름]
WHERE [컬럼이름] [연산자] ( SELECT [컬럼이름]
                            FROM[테이블이름]
                            WHERE조건식);

 

서브쿼리에 사용하는 연산자

 

비교연산자

비교연산자만 사용시, WHERE절의 서브쿼리는 반드시 결과 값이 하나의 값이어야 한다.

 

주요 연산자

주요연산자만 사용시, WHERE절의 서브쿼리는 반드시 결과 값이 하나의 컬럼이어야 한다.

단, EXISTS는 단독으로 사용하며, 결과 값이 여러컬럼이어도 된다.

 

WHERE 절의 서브쿼리 예제

 

 

 

 

 

 

5. [실습] 서브쿼리로 복잡한 조건을 하나의 쿼리로 만들어보자


[ 포켓몬 입력 쿼리 ]

DROP DATABASE IF EXISTS pokemon;
CREATE DATABASE pokemon;
USE pokemon;
CREATE TABLE mypokemon (
	   number  INT,
       name	VARCHAR(20)
);
INSERT INTO mypokemon (number, name)
VALUES (10, 'caterpie'),
	   (25, 'pikachu'),
       (26, 'raichu'),
       (133, 'eevee'),
       (152, 'chikoirita');
CREATE TABLE ability (
	   number INT,
	   type	VARCHAR(10),
       height FLOAT,
       weight FLOAT,
       attack INT,
       defense INT,
       speed int
);
INSERT INTO ability (number, type, height, weight, attack, defense, speed)
VALUES (10, 'bug', 0.3, 2.9, 30, 35, 45),
	   (25, 'electric', 0.4, 6, 55, 40, 90),
       (26, 'electric', 0.8, 30, 90, 55, 110),
	   (133, 'normal', 0.3, 6.5, 55, 50, 55),
	   (152, 'grass', 0.9, 6.4, 49, 65, 45);

 

 

MISSION (1) 내 포켓몬 중에 몸무게가 가장 많이 나가는 포켓몬의 번호를 가져와주세요.

 

SELECT number
FROM (SELECT number FROM ability ORDER BY weight DESC LIMIT 1) AS A;

 

 

MISSION (2) 속도가 모든 전기 포켓몬의 공격력보다 하나라도 작은 포켓몬의 번호를 가져와주세요.

 

SELECT number
FROM ability
WHERE speed < ANY( SELECT attack FROM ability WHERE type = 'electric');

 

 

MISSION (3) 공격력이 방어력보다 큰 포켓몬이 있다면 모든 포켓몬의 이름을 가져와주세요.

 

SELECT name
FROM mypokemon
WHERE EXISTS (SELECT * FROM ability   WHERE attack > defense);

 

 

 

6. [추가실습] 서브쿼리로 복잡한 조건을 하나의 쿼리로 만들어보자


MISSION (1)
이브이의 번호133을 활용해서, 이브이의 영문이름, 키, 몸무게를 가져와주세요.
이때, 키는 height, 몸무게는 weight이라는 별명으로 가져와주세요.

 

SELECT name, 
		(SELECT height FROM ability WHERE number = 133) AS height,
        (SELECT weight FROM ability WHERE number = 133) AS weight
FROM mypokemon
WHERE number = "133";

 

 

 

MISSION (2)
속도가 2번째로 빠른 포켓몬의 번호와 속도를 가져와주세요.

 

SELECT number, speed
FROM (SELECT number, speed, RANK() OVER(ORDER BY speed DESC) AS speed_rank 
	FROM ability ) AS A
WHERE speed_rank = 2;

 

 

MISSION (3)
방어력이 모든 전기포켓몬의 방어력보다 큰포켓몬의 이름을 가져와주세요.

 

SELECT name
FROM mypokemon
WHERE number IN (SELECT number FROM ability 
				WHERE defense > ALL(SELECT defense FROM ability WHERE  type = 'electric'));