Chapter
1. Aggregate Functions(집계함수)
(1) Count
(2) Sum
(3) Avg
(4) Min, Max
(5) Group By
(6) Having
2. Scalar Functions
(1) UPCASE
(2) LCASE
(3) MID
(4) LENGTH
(5) ROUND
(6) NOW
(7) FORMAT
3. SQL Subquery
(1) Scalar Subquery
(2) Inline View
(3) Nested Subquery
집계함수란 여러 칼럼 혹은 테이블 전체 칼럼으로부터 하나의 결과값을 반환하는 함수를 말한다. 다음과 같은 종류가 있다.
앞에서 살펴본 crime_status테이블과 police_station테이블을 통해 예제를 몇 가지 살펴보자.
다음과 같은 문법을 통해서 함수값을 구할 수 있다.
SELECT COUNT(column)
FROM tablename
WHERE condition;
예제를 살펴보자.
SELECT COUNT(*)
FROME police_station;
SELECT COUNT(DISTINCT police_station)
FROM crime_status;
select count(distinct crime_type)
from crime_status;
.
.
다음과 같은 문법을 통해서 함수값을 구할 수 있다.
SELECT SUM(column)
FROM tablename
WHERE condition;
예제를 살펴보자.
select sum(case_number)
from crime_status
where status_type='발생';
select sum(case_number)
from crime_status
where crime_type='살인' and status_type='발생';
select sum(case_number)
from crime_status
where police_station='중부' and status_type='검거';
.
.
숫자 칼럼의 평균을 계산해주는 함수이다. 다음과 같이 사용할 수 있다.
SELECT AVG(column)
FROM tablename
WHERE condition;
예시를 살펴보자.
select avg(case_number)
from crime_status
where crime_type like '폭력' and status_type like '검거';
select avg(case_number)
from crime_status
where police_station like '중부' and status_type like '발생';
select avg(case_number)
from crime_status
where crime_type like '살인' and status_type like '발생';
select avg(case_number)
from crime_status
where (police_station like '구로' or police_station like '도봉') and crime_type like '살인' and status_type like '검거';
가장 작은 값을 리턴해주는 함수이다. 다음과 같이 사용할 수 있다.
SELECT MIN(column)
FROM tablename
WHERE condition
예제를 살펴보자.
select min(case_number)
from crime_status
where crime_type like '강도' and status_type like '발생';
select min(case_number)
from crime_status
where police_station like '중부' and status_type like '검거';
select min(case_number)
from crime_status
where police_station like '광진' and status_type like '검거';
select min(case_number)
from crime_status
where police_station like '성북' and status_type like '발생';
가장 큰 값을 리턴해주는 함수이다. 다음과 같이 사용할 수 있다.
SELECT MAX(column)
FROM tablename
WHERE condition
예제를 살펴보자.
select max(case_number)
from crime_status
where crime_type like '살인' and status_type like '검거';
select max(case_number)
from crime_status
where police_station like '강남' and status_type like '발생';
select max(case_number)
from crime_status
where police_station like '영등포' and status_type like '발생';
select max(case_number)
from crime_status
where crime_type like '절도' and status_type like '검거';
.
.
그룹화하여 데이터를 조회하는 방법이다. 다음과 같이 사용한다.
SELECT col1, col2, ...
FROM tablename
GROUP BY col1, col2, ....
ORDER BY col1, col2, ...;
예제를 살펴보자.
select police_station
from crime_status
group by police_station
order by police_station;
DISTINCT를 사용하여 그룹화할 수도 있다. 단, 이때는 ORDER BY로 정렬을 시킬 수는 없다.
select distinct police_station
from crime_status;
select police_tation, sum(case_number) 발생건수
from crime_status
where status_type like '발생'
group by police_station
order by 발생건수 desc;
select police_station, avg(case_number) 평균검거건수
from crime_status
where status_type like '검거'
group by police_station
order by 평균검거건수 desc;
select police_station, status_type, avg(case_number)
from crime_status
group by police_station, status_type
limit 10;
.
.
조건에 집계함수가 포함되는 경우에 WHERE 대신 HAVING을 사용한다.
SELECT col1, col2, ...
FROM table
WHERE condition
GROUP BY col1, col2, ...
HAVING condition
ORDER BY col1, col2, ...;
예제를 살펴보자.
select police_station, sum(case_number) count
from crime_status
where status_type like '발생'
group by police_station
having count > 4000;
select police_station, avg(case_number)
from crime_status
where (crime_type like '폭력' or crime_type like '절도')
and status_type like '발생'
group by police_station
having avg(case_number) >= 2000;
select police_station, min(case_number)
from crime_status
where status_type like '검거'
group by police_station
having min(case_number) > 4
order by min(case_number) desc;
.
.
.
.
Scalar function이란 입력값을 기준으로 단일 값을 반환하는 함수이다. 다음과 같은 종류가 있다.
테이블을 통해서 몇 가지 예제로 함수를 살펴보자.
예제로 살펴볼 함수는 sandwich 테이블과 oil_price테이블이다.
영문을 대문자로 반환하는 함수이다.
SELECT UPCASE ('This is ucase test.');
select ucase(menu)
from sandwich
where price >15;
.
.
영문을 소문자로 변환한다.
예제를 살펴보자.
select lcase('This is lcase test.');
select lcase(menu)
from sandwich
where price < 5;
.
.
문자열을 반환하는 함수로 다음과 같이 사용할 수 있다.
select mid(string, start_position, lenth);
→ string: 원본 문자열
→ start: 문자열 반환 시작 위치. (첫글자는 1, 마지막 글자는 -1)
→ length: 반환할 문자열 길이
예제를 살펴보자.
select mid('This is mid test', 1, 4);
select mid('This is mid test', -4, 4);
select mid(cafe, 6,4)
from sandwich
where ranking = 11;
.
.
문자열의 길이를 반환한다.
select length(string);
select length('this is len test');
몇 가지 살펴볼 점이 있다.
select length('');
select length(' ');
select length(NULL);
select length(address), address
from sandwich
where rangking <=3;
.
.
지정한 자리에서 숫자를 반올림하는 함수이다.
select round(number , 반올림할 소수점 위치);
예제를 통해 살펴보자.
select round(315.625);
select round(315.625, 0).
select round(315.625, -1);
select ranking, price, round(price)
from sandwich
order by ranking desc
limit 3;
.
.
현재 날짜 및 시간을 반환한다.
select now();
숫자를 천단위 콤마가 있는 형식으로 반환
select format(number, 표시할 소수점 위치);
예제
select format(12345.6789, 0);
select format(12345.6789, 2);
select format(가격, 0)
from oil_price
where round(가격, -3) >= 2000;
# format을 하면 string형식이 되므로 round로 수를 비교해야 한다.
.
.
.
.
하나의 SQL문 안에 포함되어 있는 또 다른 SQL문을 말한다.
서브쿼리는 괄호로 묶어서 사용하는데, 메인쿼리가 서브쿼리를 포함하는 종속적인 관계이다.
서브쿼리는 메인쿼리의 칼럼을 사용할 수 있지만, 메인쿼리는 서브쿼리의 칼럼을 사용할 수 없다.
단일 행 또는 복수 행 비교 연산자와 함께 사용 가능하며, 서브쿼리내에서는 order by를 사용할 수 없다.
세 가지 종류로 나눌 수 있는데, 종류에 따라 사용되는 위치가 다르다.
SELECT절에서 사용하는 쿼리로, 결과는 하나의 컬럼이어여 한다.
SELECT col1, (SELELCT col2 FROM tabl2 WHERE condition)
FROM table1
WHERE condition;
예제를 살펴보자.
# 서울은평경찰서의 강도 검거 건수
SELECT case_number
FROM crime_status
WHERE police_station LIKe '은평'
AND crime_type LIKE '강도'
AND status_type LIKE '검거';
# 서울시 경찰서 전체의 평균 강도 검거 건수
SELECT avg(case_number)
FROM crime_status
WHERE crime_type like '강도'
AND status_type LIKE '검거';
나눠보면 이렇게 값을 구할 수 있는데, 여기서 두 번째 쿼리를 서브쿼리로 select문에 집어넣으면 값을 한 번에 출력할 수 있다.
# scalar subquery : 경찰서 전체의 평균 강도 검거 건수
SELECT case_number,
(SELECT avg(case_number)
FROM crime_status
WHERE crime_type like '강도' AND status_type LIKE '검거') avg
FROM crime_status
WHERE police_station LIKe '은평'
AND crime_type LIKE '강도'
AND status_type LIKE '검거';
.
.
FROM절에서 사용하는 서브쿼리로, 메인쿼리에서는 인라인 뷰에서 조회한 컬럼만 사용가능 하다.
SELECT a.column, b.column
FROM table1 a, (SELECT column1, column2, ... FROM table2) b
WHERE condition;
예제를 통해서 살펴보자
먼저 경찰서별로 가장 많이 발생한 범죄 건수를 조회해보자.
SELECT police_station, max(case_number) count
FROM crime_status
WHERE status_type LIKE '발생'
GROUP BY police_station;
데이터를 이용해서 해당 범죄 유형까지 조회하고 싶다면, 서브쿼리를 이용해서 이 범죄 건수가 같은 범죄 건수의 유형을 찾아내면 한 번에 조회할 수 있다.
SELECT c.police_station, c.crime_type, c.case_number
FROM crime_status c,
(SELECT police_station, max(case_number) count
FROM crime_status
WHERE status_type LIKE '발생'
GROUP BY police_station) m
WHERE c.police_station = m.police_station
AND c.case_number = m.count;
SELECT o.상호, o.가격, o.상표
FROM oil_price o,
(SELECT MAX(가격) 최고가, 상표
FROM oil_price
GROUP BY 상표) m
WHERE m.최고가 = o.가격
AND m.상표 = o.상표;
.
.
WHERE절에서 사용하는 서브쿼리이며, 다음과 같이 나뉜다.
→ Single Row : 하나의 열을 검색하는 서브쿼리
→ Multiple Row : 하나 이상의 열을 검색하는 서브쿼리
→ Multiple Column : 하나 이상의 행을 검색하는 서브쿼리
서브쿼리가 비교연산자와 사용되는 경우, 서브쿼리의 검색 결과는 한 개의 결과값을 가져야 한다.
SELECT column_names
FROM table_name
WHERE column_name = (SELECT column_name
FROM table_name
WHERE condition)
ORDER BY column_name;
select name
from celeb
where name = (select host from snl_show where id=1);
① IN과 사용될 때
SELECT column_names
FROM table_name
WHERE column_name IN (SELECT column_name
FROM table_name
WHERE condition)
ORDER BY column_names;
SELECT host
FROM snl_show
WHERE host IN (SELECT name
FROM celeb
WHERE job_title LIKE '%영화배우%');
② EXISTS와 사용될 때
서브쿼리 결과에 값이 있으면 반환된다.
SELECT col_names
FROM table_name
WHERE EXISTS (SELECT column_name
FROM table_name
WHERE condition)
ORDER BY column_names;
SELECT name
FROM police_station p
WHERE EXISTS (SELECT police_station
FROM crime_status c
WHERE p.name=c.reference AND case_number > 2000);
③ ANY와 사용
서브쿼리 결과 중에서 최소한 하나라도 만족하면 반환된다.
SELECT column_names
FROM table_name
WHERE column_name =ANY (SELECT column_name
FROM table_name
WHERE condition)
ORDER BY column_names;
SELECT name
FROM celeb
WHERE name = ANY (SELECT host FROM snl_show);
④ ALL과 사용
서브쿼리 결과를 모두 만족하면 반환한다.
SELECT column_names
FROM table_name
WHERE column_name = ALL (SELECT column_name
FROM table_name
WHERE condition)
ORDER BY column_names;
SELECT name
FROM celeb
WHERE name = ALL ( SELECT host
FROM snl_show
WHER id=1);
서브쿼리 내에 메인쿼리 컬럼이 같이 사용되는 경우이다.
SELECT column_names
FROM tablename a
WHERE (a.column1, a.column2, ... ) IN (SELECT b.column1, b.column2, ...
FROM tablename b
WHERE a.column_name = b.column_name)
ORDER BY column_names;
SELECT name, sex, agency
FROM celeb
WHERE (sex, agency) IN (SELECT sex,agency FROM celeb WHERE name='강동원);