[Database] 데이터 형식(Data Type) & 함수(2)
데이터 형식(Data Type)
함수
3. 문자열 함수
-- CONCAT(), CONCAT_WS()
# CONCAT() 함수
SELECT CONCAT('2024', '05', '20');
# CONCAT_WS() 함수
SELECT CONCAT_WS('/', '2024', '05', '20');
<ex1>
-- usertbl 테이블에서 아이디, 이름, 전화번호를 조회
SELECT userID AS "아이디",
NAME AS "이름",
CONCAT( mobile1, mobile2) AS 전화번호
FROM usertbl;
<ex2>
-- employee 테이블에서 급여 조회
SELECT CONCAT(emp_name, '님의 급여는 ', salary, '입니다.') AS "급여"
FROM employee;
-- ELT(), FIELD(), FIND_IN_SET(), INSTR(), LOCATE() 함수
# ELT() : 위치번째에 해당하는 문자열을 반환
# 2가 입력되었기 때문에 2에 해당하는 '둘'을 반환
SELECT ELT(2, '하나', '둘', '셋');
# FIELD() : 찾을 문자열의 위치를 찾아서 반환
# '둘' 에 해당하는 문자열이 2번째에 있기 때문에 2를 반환
SELECT FIELD('둘', '하나', '둘', '셋');
# FIND_IN_SET() : 찾을 문자얼의 위치를 찾아서 반환
# 하나의 문자열을 ,(콤마)로 구분하여 찾음
# '둘' 에 해당하는 문자열이 ,(콤마)를 기준으로 2번째에 있기 때문에
# 2 를 반환
SELECT FIND_IN_SET('둘', '하나,둘,셋');
# INSTR() : 기준 문자열에서 부분 문자열을 찾아서 그 시작 위치를 반환
# '둘'이 시작위치가 3번째이기 때문에 3을 반환
SELECT INSTR('하나둘셋', '둘');
# LOCATE() : INSTR()과 순서만 다르고 결과가 동일
# '둘'이 시작위치가 3번째이기 때문에 3을 반환
SELECT LOCATE('둘', '하나둘셋');
<ex1>
-- employee 테이블에서 이메일의 @ 위치값 출력
SELECT email,
INSTR(email, '@')
FROM employee;
-- INSERT() 함수
# INSERT('기준 문자열', 삽입 시작 위치, 삭제될 문자 개수, '삽입할 문자')
#1 : 문자 4개 삭제
SELECT INSERT('ABCEDFGHI', 3, 4, '@@@@');
#2 : 문자 2개 삭제
SELECT INSERT('ABCEDFGHI', 3, 2, '@@@@');
<ex1>
-- employee 테이블에서 사원명, 주민등록번호 조회
SELECT emp_name AS "이름",
INSERT(emp_no, 9, 6, '******') AS "주민등록번호"
FROM employee;
-- LEFT(), RIGHT() 함수
# LEFT() : 기준문자열를 왼쪽에서 3개 잘라내어 출력
SELECT LEFT('ABCEDFGHI', 3);
# RIGHT() : 기준문자열를 오른쪽에서 3개 잘라내어 출력
SELECT RIGHT('ABCEDFGHI', 3);
<ex1>
-- employee 테이블에서 사원명, email의 ID만을 출력
SELECT emp_name,
LEFT(email, INSTR(email, '@')-1) AS 'ID'
FROM employee;
-- UPPER(), LOWER() 함수
# UPPER() : 소문자를 모두 대문자를 변환
SELECT UPPER('abcDEF');
# LOWER() : 대문자를 모두 소문자를 변환
SELECT LOWER('abcDEF');
-- LPAD(), RPAD() 함수
# LPAD() : 왼쪽에 남은 문자열 수 넣음
# 문자열을 넣어주지 않으면 공백
SELECT LPAD('HELLO', 10), LPAD('HELLO', 10, '#');
# RPAD() : 오른쪽에 남은 문자열 수 넣음
# 문자열을 넣어주지 않으면 공백
SELECT RPAD('HELLO', 10), RPAD('HELLO', 10, '#');
<ex1>
-- employee 테이블에서 사원명, 주민등록번호 출력
SELECT emp_name,
RPAD(LEFT(emp_no, 8), 14, '*') AS "주민등록번호"
FROM employee;
-- LTRIM(), RTRIM(), TRIM() 함수 사용
# LTRIM(): 왼쪽 공백만 제거
SELECT LTRIM(' HELLO ');
# RTRIM(): 오른쪽 공백만 제거
SELECT RTRIM(' HELLO ');
# TRIM(): 양쪽 공백만 제거
SELECT TRIM(' HELLO ');
-- TRIM(방향 자를 문자열 FROM 문자열)
#1
# 양쪽 공백을 모두 지움
SELECT TRIM(BOTH ' ' FROM ' HELLO ');
#2
# 양쪽 'Z'문자를 모두 지움
SELECT TRIM(BOTH 'Z' FROM 'ZZZZZHELLOZZZZZ');
#3
# 중간에 삽입된 'Z'는 지워지지 않음
SELECT TRIM(BOTH 'Z' FROM 'ZZZZZHEZLLOZZZZZ');
#4
# 왼쪽에 삽입된 'Z'만 지움
SELECT TRIM(LEADING 'Z' FROM 'ZZZZZHEZLLOZZZZZ');
#5
# 오른쪽에 삽입된 'Z'만 지움
SELECT TRIM(TRAILING 'Z' FROM 'ZZZZZHEZLLOZZZZZ');
-- REPEAT(), SPACE() 함수
# REPEAT() : 특정문자열 N번 반복
# SPACE() : 공백을 N칸 넣음
SELECT REPEAT('HELLO', 3), SPACE(10);
-- REVERSE() 함수
# REVERSE() : 문자열을 뒤집어서 출력
SELECT REVERSE("HELLO");
-- REPLACE() 함수
# Replace('문자열', '원래 문자열', '바꿀 문자열')
SELECT REPLACE('hong123@naver.com', 'naver.com', 'gmail.com');
<ex1>
-- employee 테이블에서 이메일의 kh.or.kr을 naver.com 변경해서 조회
SELECT emp_name AS "사원명",
REPLACE(email, "kh.or.kr", "naver.com")
FROM employee;
<ex2>
-- employee 테이블에서 이메일의 아이디만을 조회
SELECT emp_name AS "사원명",
REPLACE(email, "@kh.or.kr", "") AS "아이디"
FROM employee;
-- SUBSTRING() 함수
#1
# SUBSTRING(문자열, 시작위치, 길이)
SELECT SUBSTRING('대한민국 만세', 3, 2);
#2
# SUBSTRING(문자열, 시작위치) : 시작위치만 입력하면 끝까지
SELECT SUBSTRING('대한민국 만세', 3);
#3
# 음수값은 뒤에서부터를 의미
SELECT SUBSTRING('대한민국 만세', -2, 2);
<ex1>
-- employee 테이블에서 이름, 아이디, 성별 조회
SELECT emp_name,
SUBSTRING(email, 1, INSTR(email, '@')-1) AS '아이디',
IF(SUBSTRING(emp_no, 8, 1) = 1, '남자', '여자') AS '성별'
FROM employee;
-- SUBSTRING_INDEX() 함수
#1
# 양수 : 왼쪽에서 부터 첫번째 구분자를 찾고 오른쪽 부분을 삭제
SELECT SUBSTRING_INDEX('cafe.naver.com', '.', 1);
#2
# 음수 : 오른쪽에서 부터 첫번째 구분자를 찾고 왼쪽 부분을 삭제
SELECT SUBSTRING_INDEX('cafe.naver.com', '.', -1);
<ex1>
-- employee 테이블에서 아이디 조회
SELECT emp_name AS '사원명',
SUBSTRING_INDEX(email, '@', 1) AS '아이디'
FROM employee;
4. 수학 함수
-- ABS() 함수: 절대값 출력 함수
SELECT ABS(100), ABS(-100),
ABS(10.9), ABS(-10.9);
-- CEILING(), FLOOR(), ROUND(), TRUNCATE() 함수
# CEILING() : 올림 함수
SELECT CEILING(4.3);
# FLOOR() : 내림 함수
SELECT FLOOR(4.7);
# ROUND(x) : ROUND(X, 0)과 동일
SELECT ROUND(4.355), ROUND(4.355, 0);
# ROUND(x, D) : 소수점 D자리까지 반올림
# D 양수 : 소수점 기준
# D 음수 : 자연수 기준
SELECT ROUND(4.355, 2), ROUND(14.355, -1);
# TRUNCATE() : 소수점 기준으로 정수 위치까지 구하고 나머지를 삭제
SELECT TRUNCATE(123.456, 0), TRUNCATE(123.456, 1);
-- MOD() 함수
# MOD(숫자1, 숫자2) : 나머지 함수
# 숫자1을 숫자2로 나눈 나머지값을 반환
SELECT MOD(157, 10) , 157 % 10, 157 MOD 10;
-- RAND() 함수
#1
# RAND() : 0<=X<=1 범위의 값이 랜덤으로 출력
SELECT RAND(), RAND(), RAND();
#2
# RAND() 함수 범위지정
SELECT RAND() * 100 -- 0.0 ~ 99.99999
FLOOR(RAND() * 100), -- 0 ~99
FLOOR(RAND() * 100) +1 ; -- 1 ~ 100
-- POW(), SQRT(), SIGN() 함수
# POW() : 거듭 제곱 함수
SELECT POW(2,3);
# SQRT() : 제곱근 함수
SELECT SQRT(9);
# SIGN() : 양수, 0, 음수 판별하는 함수
SELECT SIGN(100), SIGN(0), SIGN(-100);
5. 날짜 및 시간 함수
-- ADDDATE(), SUBDATE()함수
#1
# ADDDATE() : 날짜 더하는 함수
SELECT ADDDATE('2024-05-20', INTERVAL 31 DAY), -- 31일 더하기
ADDDATE('2024-05-20', INTERVAL 1 MONTH), -- 한달 더하기
ADDDATE('2024-05-20', INTERVAL 1 YEAR); -- 1년 더하기
#2
# SUBDATE() : 날짜를 빼는 함수
SELECT SUBDATE('2024-05-20', INTERVAL 31 DAY), -- 31일 빼기
SUBDATE('2024-05-20', INTERVAL 1 MONTH), -- 한달 빼기
SUBDATE('2024-05-20', INTERVAL 1 YEAR) -- 1년 빼기
#1
# ADDTIME() : 시간을 더하는 함수
SELECT ADDTIME('2024-05-20 09:00:00', '01:10:30'), -- 1시간 10분 30초 더하기
ADDTIME('09:00:00', '02:20:50'); -- 2시간 20분 50초 더하기
#2
# ADDTIME() : 시간을 더하는 함수
SELECT SUBTIME('2024-05-20 09:00:00', '01:10:30'), -- 1시간 10분 30초 빼기
SUBTIME('09:00:00', '02:20:50'); -- 2시간 20분 50초 빼기
<ex1>
-- employee테이블에서 사원명, 입사일, 인턴(3개월) 종료일 구하기
SELECT emp_name AS '사원명',
hire_date AS '입사일',
ADDDATE(hire_date, INTERVAL 3 MONTH) AS '인턴 종료일'
FROM employee;
-- CURDATE(), CURTIME(), NOW(), SYSDATE() 함수
SELECT CURDATE(), -- 현재 날짜
CURTIME(), -- 현재 시간
NOW(), -- 현재 날짜와 시간
SYSDATE(); -- 현재 날짜와 시간
#1
-- YEAR(), MONTH(), DAY() 함수 : DATE 타입을 입력 받음
SELECT YEAR(CURDATE()), -- 년을 출력
MONTH(CURDATE()), -- 월을 출력
DAY(CURDATE()); -- 일을 출력
#2
-- HOUR(), MINUTE(), SECOND() : TIME 타입을 입력받음
SELECT HOUR(CURTIME()), -- 시간을 출력
MINUTE(CURTIME()), -- 분을 출력
SECOND(CURTIME()); -- 초를 출력
-- DATEDIFF(), TIMEDIFF() 함수
#1
#DATEDIFF(날짜1, 날짜2) : 날짜 1에서 날짜 2를 뺌
SELECT DATEDIFF('2022-05-20', CURDATE()),
DATEDIFF(CURDATE(), '2022-05-20');
#2
# TIMEDIFF(시간1, 시간2) : 시간 1에서 시간 2를 뺌
SELECT TIMEDIFF('09:00:00', CURTIME()),
TIMEDIFF(CURTIME(), '09:00:00');
<ex1>
-- employee 테이블에서 직원명, 입사일, 근무 일수 조회
SELECT emp_name AS '직원명',
hire_date AS '입사일' ,
DATEDIFF(CURDATE(), hire_date) AS '근무 일수'
FROM employee;
-- DAYOFWEEK(), MONTHNAME(), DAYOFYEAR(), LAST_DAY() 함수 : 날짜 데이터를 입력받음
#1
# DAYOFWEEK() : 날짜의 요일을 반환
# 1: 일요일, 2: 월요일, ..., 7: 토요일
SELECT DAYOFWEEK(CURDATE());
#2
# MONTHNAME() : 날짜의 월의 이름을 반환
SELECT MONTHNAME(CURDATE());
#3
# DAYOFYEAR() : 1년 중 몇 번째 날짜인지를 반환
SELECT DAYOFYEAR(CURDATE());
#4
# LAST_DAY() : 주어진 날짜의 달에 해당하는 마지막 날짜를 반환
SELECT LAST_DAY(CURDATE());
<ex1>
-- employee 테이블에서 직원명, 입사일, 급여일(매달 마지막 날) 조회
SELECT emp_name AS '직원명',
hire_date AS '입사일',
LAST_DAY(CURDATE()) AS '급여일'
FROM employee;
-- MAKEDAY(), MAKETIME() 함수
#1
# MAKEDATE(연도, 정수) : 해당 '연도'에 '정수'만큼 지난 날짜를 반환
SELECT MAKEDATE(2024, 100);
#2 MAKETIME(시, 분, 초) : 입력값에 해당하는 시간을 반환
SELECT MAKETIME(22, 58, 25);
-- PERIOD_ADD(), PERIOD_DIFF(), QUARTER(), TIME_TO_SEC() 함수
#1
# PERIOD_ADD(연월, 개월 수) : 연월에서 개월만큼의 개월이 지난 연월을 반환
SELECT PERIOD_ADD(202405, 11);
#2
# PERIOD_DIFF(연월 1, 연월 2) : 연월 1 - 연월 2의 개울 수 반환
SELECT PERIOD_DIFF(202305, 202405);
#3
# QUARTER(날짜) : 날짜가 4분기 중 몇 분기에 해당하는지 반환
SELECT QUARTER(CURDATE());
#4
# TIME_TO_SEC(시간) : 시간을 초 단위로 반환
SELECT TIME_TO_SEC(CURTIME());
6. 시스템 정보 함수
7. 윈도우 함수
- 순위 윈도우 함수에는 ROW_NUMBER(), RANK(), DENSE_RANK(), NTILE() 등의 함수가 존재
- 순위 윈도우 함수를 사용하면 데이터를 순서대로 번호 매기거나, 특정 조건에 따라 순위(등수)를 매길 수 있음
-- 윈도우 함수 "순위 함수"
-- ROW_NUMBER() 함수 : 순번을 매김
<ex1>
-- usertbl 테이블에서 키가 큰 순으로 순위를 매겨서 순위, 이름, 주소,
-- 키를 조회
# OVER절에 정렬 조건 기입
SELECT ROW_NUMBER() OVER(ORDER BY height DESC, NAME ASC) AS 'RANK',
NAME AS "이름",
addr AS "주소",
height AS "키"
FROM usertbl;
<ex2>
-- usertbl 테이블에서 지역별로 순위를 배겨서 주소 순위, 이름, 키 조회
SELECT addr AS '주소',
ROW_NUMBER() OVER(PARTITION BY addr ORDER BY height DESC, NAME ASC) AS '주소별 순위',
NAME AS '이름',
height AS '키'
FROM usertbl
ORDER BY addr;
-- 윈도우 함수 "순위 함수"
# RANK() 함수 : 동일한 순위 이후의 등수를 동일한 인원수만큼 건너뛰고 증가
-- usertbl 테이블에서 키가 큰 순으로 순위를 매겨서 순위, 이름, 주소, 키를 조회
SELECT RANK() OVER(ORDER BY height DESC, NAME ASC) AS 'RANK',
NAME AS "이름",
addr AS "주소",
height AS "키"
FROM usertbl;
<ex2>
-- employee 급여가 높은 순서대로 순위 매겨서 순위, 직원명, 급여 조회
SELECT RANK() OVER(ORDER BY salary DESC, emp_name ASC) AS 'RANK',
emp_name AS '직원명',
salary AS '급여'
FROM employee;
-- 윈도우 함수 "순위 함수"
# DENSE_RANK() 함수 : 동일한 순위 이후의 등수를 1 증가
<ex1>
-- usertbl 테이블에서 키가 큰 순으로 순위를 매겨서 순위, 이름, 주소, 키를 조회
SELECT DENSE_RANK() OVER(ORDER BY height DESC, NAME ASC) AS 'RANK',
NAME AS "이름",
addr AS "주소",
height AS "키"
FROM usertbl;
-- 윈도우 함수 "순위 함수"
# NTILE(x) 함수 : 전체 인원을 어떠한 기준 순서로 세운 후에 x개의 그룹으로 분할
<ex1>
# usertbl 테이블에서 키가 순서로 세운 후에 3개의 그룹을 분할
SELECT NTILE(2) OVER(ORDER BY height DESC, NAME ASC) AS 'RANK',
NAME AS "이름",
addr AS "주소",
height AS "키"
FROM usertbl;
- 분석 윈도우 함수에는 LEAD(), LAG(), FIRST_VALUE(), LAST_VALUE(), CUME_DIST() 등의 함수가 존재
- 분석 윈도우 함수를 사용하면 현재 행의 이전 행이나 다음 행의 데이터를 참조하거나, 윈도우의 첫 값이나 마지막 값을 가져올 수 있음
-- 윈도우 함수 "분석 함수"
# LEAD(column, n) : n 단위로 다음 등수의 데이터를 가져옴
<ex1>
-- usertbl 테이블에서 키 순서대로 정렬 후 다음 사람과 키 차이를 조회
SELECT NAME AS '직원명',
addr AS '주소',
height AS '키',
height - LEAD(height, 1) OVER(ORDER BY height DESC) AS '다음 등수 키 차이'
FROM usertbl;
-- 윈도우 함수 "분석 함수"
# LAG(column, n) : n 단위로 이전 등수의 데이터를 가져옴
<ex1>
-- usertbl 테이블에서 키 순서대로 정렬 후 다음 사람과 키 차이를 조회
SELECT NAME AS '직원명',
addr AS '주소',
height AS '키',
height - LAG(height, 1) OVER(ORDER BY height DESC) AS '이전 등수 키 차이'
FROM usertbl;
-- 윈도우 함수 "분석 함수"
# FIRT_VALUE(column) : 특정 column의 데이터 중 순위의 가장 첫 번째 값을 가져옴
<ex1>
-- 지역별로 가장 키가 큰 사람과의 키 차이를 조회
SELECT addr AS '주소',
NAME AS '이름',
height AS '키',
height - FIRST_VALUE(height) OVER(PARTITION BY addr ORDER BY height DESC) AS '지역별로 가장 키가 큰 사람과의 키 차이'
FROM usertbl
ORDER BY addr;