SELECT 문
에서 사용됨집계함수 | 기능 |
---|---|
COUNT | 테이블의 행 수 반환 |
SUM | 테이블의 열 합계 반환 |
AVG | 테이블의 열 평균 반환 |
MIN | 테이블의 열 최소값 반환 |
MAX | 테이블의 열 최대값 반환 |
# 나이 컬럼의 값이 30, 40, 50이 아니면 나이 컬럼을 NULL로 업데이트해주는 쿼리
UPDATE THEGLORY SET 나이 = NULL WHERE 나이 NOT IN (30, 40, 50);
SELECT AVG(나이), SUM(나이)/COUNT(*), AVG(IFNULL(나이, 0)) FROM THEGLORY;
< 기타 집계 함수 >
< COUNT 예시 >
SELECT COUNT(*) FROM ANIMAL_INS;
COUNT(*)
을 할 경우 주어진 행에 값이 하나라도 있으면 COUNT가 됨COUNT(NAME)
을 하게 될 경우엔 NAME 컬럼의 값이 NULL이 아닌 행의 개수가 카운트 됨< MIN 예시 >
-- 1회차 강의 때 LIMIT를 이용해 풀었던 문제입니다. MIN을 이용해서 더 쉽게 풀 수 있어요.
SELECT MIN(DATETIME) FROM ANIMAL_INS;
집계함수
에 그룹(기준)
이 더해진 개념<SQL 작성방법>
select
기준컬럼,
집계함수(기준컬럼을 기준으로 여러개의 집계함수 동시사용 가능)
from
테이블명
where
조건 #(생략가능)
group by
기준컬럼;
(1) SELECT 뒤 기준컬럼
작성
(2) 집계함수
(COUNT, MAX, MIN, AVG, SUM) 작성
(3) WHERE 절 뒤 GROUP BY 기준컬럼
작성 (WHERE 절은 생략 가능)
📌 SELECT문에 기준컬럼
과 집계함수
가 둘 다 있을 때는 GROUP BY 필수!
<문법 예시>
SELECT 성별, 이름, sum(나이) FROM THEGLORY t GROUP BY 성별, 이름;
ex) 입양 시각 구하기(GROPU BY + COUNT + DATE_FORMAT() + BETWEEN)
SELECT DATE_FORMAT(DATETIME, "%H") AS HOUR, COUNT(*) FROM ANIMAL_OUTS
WHERE DATE_FORMAT(DATETIME, "%H") BETWEEN 9 AND 19
GROUP BY HOUR
ORDER BY HOUR;
< HAVING ≠ WHERE ! >
# 집계함수, GROUP BY절, HAVING을 함께 사용하는 SQL문
select
기준컬럼,
집계함수(기준컬럼을 기준으로 여러개의 집계함수 동시사용 가능)
from
테이블명
where
조건 #(생략가능)
group by
기준컬럼
having
조건식;
필터링 구문 | 필터링 시점 |
---|---|
WHERE | GROUP BY 전 데이터 필터링 |
HAVING | GROUP BY 후 결과값을 가지고 데이터 필터링 |
ex) 동명 동물 수 찾기
Q. 동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성 / 이때 결과는 이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회
SELECT NAME, COUNT(*) AS COUNT
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
GROUP BY NAME
HAVING NAME >=2
ORDER BY NAME
중간테이블의 역할
<사용 이유>
<실행 순서>
<특징>
<위치에 따른 구분>
위치 | 명칭 |
---|---|
SELECT 절 | 스칼라 서브쿼리 |
FROM 절 | 인라인 뷰 |
WHERE, HAVING 절 | 중첩 서브쿼리 |
SELECT 이름, 나이, (SELECT AVG(나이) FROM THEGLORY) FROM THEGLORY;
SELECT *,
(
SELECT AUTHOR_NAME
FROM AUTHOR A WHERE A.AUTHOR_ID=B.AUTHOR_ID
)
FROM BOOK B;
뷰
: 저장 장치 내에 물리적으로 존재하진 않는 가상 테이블)select x.나이, x.직업
from(select *
from basic.theglory
where 나이>=33
)as x
ex) 인라인 뷰로 Join 하기
select x.나이, x.직업, y.결제금액
from(select 나이, 직업, 이름
from basic.theglory
where 나이>=33
)as x, theglory2 y
WHERE x.이름 = y.이름;
select *
from basic.theglory
where 나이 > (select 나이 from basic.theglory where 이름='문동은');
select *
from basic.theglory
where 나이 > 40;
<중첩 서브 쿼리 구분하기>
1. 메인 쿼리와의 관계에 따른 구분
설명 | |
---|---|
비연관 서브쿼리 | 메인쿼리와 관계를 맺고 있지 않음 / 서브 쿼리 내 메인 쿼리의 컬럼이 존재하지 않음 |
연관 서브쿼리 | 메인쿼리와 관계를 맺고 있음 / 서브 쿼리 내 메인 쿼리의 컬럼 존재 |
select * from theglory
where 나이 > (select 나이 from basic.theglory where 이름 = '문동은');
SELECT * FROM REST_INFO A
WHERE FAVORITES = (SELECT MAX(FAVORITES) FROM REST_INFO B WHERE B.FOOD_TYPE = A.FOOD_TYPE)
WHERE FAVORITES = (SELECT MAX(FAVORITES) FROM REST_INFO B WHERE B.FOOD_TYPE = A.FOOD_TYPE)
: 서브쿼리가 반환하는 값과 A 테이블의 Favorites 값을 비교하는 조건B.FOOD_TYPE = A.FOOD_TYPE
) 레코드 중 즐겨찾기 수가 가장 많은 값을 찾는 서브쿼리WHERE B.FOOD_TYPE = A.FOOD_TYPE
: 메인 쿼리(A테이블) 에서 현재 처리 중인 레코드의 FOOD_TYPE
과 동일한 FOOD_TYPE
을 가진 레코드를 B 테이블에서 찾음SELECT MAX(FAVORITES)
: 위 조건을 만족하는 레코드들 중 FAFORITES
가 가장 큰 값을 선택WITH 이름정의 AS (
SELECT *
FROM 테이블명
)
SELECT * FROM 이름정의;
<반올림&올림&내림함수 - ROUND() / FLOOR() / CEIL()>
ROUND
: 숫자, 반올림할 자릿수(몇자리까지 남길것인지)SELECT ROUND(3.14, 1); --> 3.1
FLOOR(숫자)
: 소수점 이하 모두 버림SELECT
FLOOR(PRICE / 10000) * 10000 AS PRICE_GROUP, -- 가격을 만 단위로 그룹화
COUNT(*) AS PRODUCTS -- 해당 가격대에 속하는 상품 개수
FROM
PRODUCT
GROUP BY
PRICE_GROUP -- 가격대별로 그룹화
ORDER BY
PRICE_GROUP ASC; -- 가격대를 기준으로 오름차순 정렬
CEIL(숫자)
: 소수점 이하 모두 올림SELECT CEIL(3.14);
<문자열 자르기 함수 - SUBSTRING(), SUBSTRING_INDEX(), LEFT(), RIGHT()>
SUBSTRING
(문자열, 시작 위치값, 가져올 길이값)SELECT substring("일이삼사오육칠팔구십", 3, 5); --> 삼사오육칠
SUBSTRING_INDEX
(문자열, 구분자, 구분자 INDEX값)SELECT SUBSTRING_INDEX('사과,바나나,딸기,포도', ',', 2); --> 사과, 바나나
# 중간에 있는 값 선택. (-1은 뒤에서부터 세기)
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('사과,바나나,딸기,포도', ',', 2), ',', -1); --> 바나나
LEFT (문자열, 시작 위치값)
: 왼쪽부터 값을 가져옴SELECT LEFT("일이삼사오육칠팔구십", 3); --> 일이삼
RIGHT (문자열, 시작 위치값)
: 오른쪽부터 값을 가져옴SELECT RIGHT("일이삼사오육칠팔구십", 3); --> 팔구십