- DDL(Data Definition Language) : 데이터 정의어 - create, alter, drop
- DML(Data Manipulation Language) : 데이터 조작어 - insert, update, delete
- DCL(Data Control Language) : 데이터 제어어 - grant, revoke
- TCL(Transaction Control Language) : 트랜잭션 제어어 - commit, rollback
SQL
함수란 하나의 큰 프로그램에서 반복적으로 사용되는 부분들을 분리한 작은 서브 프로그램이다.
호출(call)하고, 실행에 대한 결과를 리턴(return)하는 방식으로 사용한다.
함수의 유형 : 단일행 함수(n개의 입력에 대한 n개의 출력), 복수행 함수(n개의 입력에 대한 1개의 출력)
-- 단일행함수 - 문자
SELECT *
FROM employee;
SELECT emp_name,
LENGTH(emp_name) -- select절에 함수 정의. 레코드에 변화 없으므로 당일행함수
FROM employee;
SELECT emp_name,
LENGTH(emp_name),
CHAR_LENGTH(emp_name)
FROM employee;
SELECT CHAR(65);
-- 문자열 연결함수(concat)
SELECT concat(emp_name, '님')
FROM employee;
-- 문자열(대문자, 소문자) - lower(), upper()
SELECT LOWER('HELLO'), UPPER('hello');
-- LPAD(문자열, 길이, [원하는 문자]), RPAD() : 자릿수를 고정하여 빈 공간을 원하는 문자로 채우는 함수 -> 정렬에서 자주 사용
SELECT email AS `원본데이터`,
LENGTH(email) AS `원본길이`,
LPAD(email, 20, '*') AS `우측정렬`,
RPAD(email, 20, '*') AS `좌측정렬`,
LENGTH(LPAD(email, 20, '*')) AS `중첩함수` -- 함수는 함수를 중첩할 수 있다
FROM employee;
-- 인덱스를 이용해서 특정 위치의 문자를 찾을 수 있는 함수 : elt(인덱스번호, 문자열....)
-- instr('문자열', '부분문자열')
SELECT ELT(2 , '1', '2', '3', '4'); -- 인덱스 번호는 1번부터 시작한다 e.g.) 1번인덱스의 값: 1, 2번인덱스의 값: 2 .....
SELECT email,
INSTR(email, '.')
FROM employee;
SELECT email,
INSTR(email, 'c') -- 부분문자열의 대소문자를 구별하지 않는다.
FROM employee;
/*
SELECT email,
INSTR(email, 'c', -1) -- error. 역방향 검색을 지원하지 않는다.
FROM employee;
*/
-- find_in_set(찾을 문자, 문자열 리스트) : 찾는 문자의 인덱스 반환
SELECT FIND_IN_SET('둘', '하나,둘,셋,넷');
-- 문자열에서 특정 부분 추출 left(), right()
SELECT LEFT('abcdefg', 3), RIGHT('abcdefg', 3);
-- 문자열 함수 LTRIM/RTRIM, TRIM
-- 제거(패턴을 제거하는 의미는 아님)
-- 기본 공백을 제거. 문자 사이에 껴있는 공백은 제거되지 않음
-- 고정길이 자료형에서 사용되지 않은 데이터공간을 제거해줄 때 주로 사용
-- 공백이 아닌 특정 문자를 제거
-- TRIM(BOTH, LEADING, TRAILING) 디폴트값은 BOTH
SELECT LTRIM(' tech'), RTRIM('tech '), TRIM(' tech '); -- 공백제거 후 왼쪽정렬한 결과가 출력된다
SELECT TRIM(BOTH '123' FROM '123tech123'),
TRIM(LEADING '123' FROM '123tech123'),
TRIM(TRAILING '123' FROM '123tech123'),
TRIM(BOTH '213' FROM '123tech123'); -- TRIM()은 패턴을 제거하는 의미가 아니기 때문에 '213'을 하나의 문자로 보고 '123tech123'에는 없는 문자이므로 제거 x
-- 문자열 반복
SELECT repeat('encore', 3);
-- 문자열 치환
SELECT REPLACE('오늘은 즐거운 불금 즐겨보자', '즐겨보자', '놀아보자');
-- 중요
-- substring(문자열, 시작위치, 길이) or (문자열 from 시작위치 for 길이)
-- substring_index(문자열, 구분자, 횟수)
SELECT SUBSTRING('this is a encore', 6, 2),
SUBSTRING('this is a encore' FROM 6 FOR 2);
SELECT SUBSTRING_INDEX('www.encore.com', '.', 2), -- 두번째에 위치한 .을 기준으로 split한 데이터를 리턴
SUBSTRING_INDEX('www.encore.com', '.', -1);
SELECT *
FROM employee;
-- 요구사항1) 메일 아이디만 추출
-- 요구사항2) 입사년도만 추출
-- 요구사항3) 주민번호 앞 6자리만 추출
-- 요구사항4) 입사일의 출력 포맷을 xxxx년xx월xx일 형식으로 출력
SELECT SUBSTRING(email, 1, INSTR(email, '@') - 1)
FROM employee;
SELECT SUBSTRING(hire_date, 1, 4)
FROM employee;
SELECT SUBSTRING(emp_no, 1, 6)
FROM employee;
SELECT SUBSTRING_INDEX(emp_no, '-', 1)
FROM employee;
SELECT CONCAT(SUBSTRING(hire_date, 1, 4), '년', SUBSTRING(hire_date, 6, 2), '월', SUBSTRING(hire_date, 9, 2), '일')
FROM employee;
-- 데이터 형식과 형변환
USE sqldb;
-- cast(표현식 as 데이터 형식 [길이] ), 묵시적 형변환
-- 다른 자료형으로 형변환을 시키는 경우 데이터의 길이도 함께 표시해줘야한다
SELECT *
FROM usertbl;
SELECT *
FROM buytbl;
-- 평균(avg) 구매 개수를 확인하고 싶다면?
SELECT AVG(amount) AS `평균 구매 개수`
FROM buytbl;
SELECT CAST(AVG(amount) AS INT) AS `평균 구매 개수` -- 반올림한 결과 반환. int == integer == signed integer
FROM buytbl;
-- 구매번호, 총 금액(cast를 사용하고), 구매액(cast를 사용하지 않고)
SELECT num,
CAST(price AS VARCHAR(10)) AS `금액`,
CAST(amount AS VARCHAR(10)) AS `수량`,
CONCAT(CAST(price AS VARCHAR(10)), ' * ', CAST(amount AS VARCHAR(10)), ' = ') AS `총 금액`,
price * amount AS `구매액`
FROM buytbl;
SELECT '100' + '100'; -- 묵시적 형변환
SELECT CAST('100' AS INT) + CAST('100' AS INT); -- 문자열을 정수로 형변환할때는 데이터의 길이를 지정하면 안된다
USE encore;
SELECT *
FROM employee;
-- 사원테이블에서 사원의 주민번호 앞 6자리와 뒤 7자리를 나누어서 더하기한 결과를 출력한다면?
SELECT LEFT(emp_no, 6),
RIGHT(emp_no, 7),
LEFT(emp_no, 6) + RIGHT(emp_no, 7),
CAST(LEFT(emp_no, 6) AS INT) + CAST(RIGHT(emp_no, 7) AS INT)
FROM employee;
-- 숫자함수
SELECT ABS(-100), -- absolute 절댓값
CEILING(4.7), -- 올림
FLOOR(3.2), -- 내림
ROUND(5.5), -- 반올림
TRUNCATE(123.1234567, 4); -- 절삭. 나머지는 잘라버림(반올림x). 자릿수가 양수면 실수자릿수, 음수면 정수자릿수
-- 날짜함수(Date)
SELECT NOW(),
SYSDATE(),
CURDATE(),
CURTIME();
-- 날짜 연산을 하고 싶다면? adddate(date, interval expr type), date_add()
-- 사원테이블에서 입사일을 기준으로 근무한지 20년이 되는 일자를 조회하고 싶다면?
SELECT *
FROM employee;
SELECT ADDDATE(CURDATE(), 2),
ADDDATE(CURDATE(), INTERVAL 2 DAY),
ADDDATE(CURDATE(), INTERVAL 2 MONTH),
ADDDATE(CURDATE(), INTERVAL 2 YEAR);
SELECT DATE_ADD(hire_date, INTERVAL 20 YEAR)
FROM employee;
-- 오늘 날짜를 기준으로 근속년수가 25년 이상인 사원의 정보를 검색한다면?
-- datediff(날짜, 날짜)
SELECT *
FROM employee
WHERE DATEDIFF(CURDATE(), hire_date) >= 25 * 365;
SELECT emp_name,
hire_date,
ROUND(DATEDIFF(CURDATE(), hire_date) / 365) AS `근속년수`
FROM employee
WHERE DATEDIFF(CURDATE(), hire_date) >= 25 * 365;
CREATE TABLE test_coupon_tbl(
str_date DATE,
end_date DATE
);
SELECT *
FROM test_coupon_tbl;
INSERT INTO test_coupon_tbl VALUES(NOW(), ADDDATE(NOW(), INTERVAL 60 DAY));
-- subdate(날짜, 차이), subtime()
SELECT SUBDATE(CURDATE(), INTERVAL 30 DAY),
SUBDATE(CURDATE(), INTERVAL 1 MONTH);
-- year(날짜), month(날짜), day(날짜)
-- hour(), minute(), second()
SELECT cast(YEAR(hire_date) AS CHAR) '년',
cast(MONTH(hire_date) AS CHAR) '월',
cast(DAY(hire_date) AS CHAR) '일'
FROM employee;
-- SQL 흐름을 제어하는 함수들 if ~ else
SELECT if(100 > 200, '참', '거짓');
-- case 값 when 비교 then 참 else 거짓 end : ANSI 표준
-- case when 조건 then 결과
SELECT CASE 10
when 1 then '일'
when 10 then '십'
ELSE '내가 원하는 값이 아님'
END AS `구분`;
-- 부서번호가 50번인 사원의 이름, 주민번호, 성별을 출력한다면?
SELECT emp_name,
emp_no,
if(SUBSTRING(emp_no, 8, 1) = '1', '남', '여') AS 'gender'
FROM employee
WHERE dept_id = '50';
-- 사원테이블에서 남자사원만 검색해보기
SELECT *
FROM employee
WHERE SUBSTRING(emp_no, 8, 1) = '1';
-- 사원테이블에서 남자사원의 이름, 주민번호, 성별을 출력한다면?
SELECT emp_name,
emp_no,
'남자' AS 'gender'
FROM employee
WHERE SUBSTRING(emp_no, 8, 1) = '1';
-- 사원테이블에서 직급이 J4인 사원의 사원번호, 이름, 사수번호를 검색해보자
-- 추가적인 요구사항으로 사수번호가 없는 사원의 mgr_id 컬럼에 '관리자'라는 값을 삽입한다면?
SELECT emp_id,
emp_name,
case
when mgr_id IS NOT NULL then mgr_id
when null IS NULL then '관리자'
END AS `관리자`
FROM employee
WHERE JOB_ID = 'J4';
-- 사원의 급여등급을 나눠보고 싶다
-- 300만원 이하면 초급, 400만원 이하면 중급, 이상이면 고급
-- 사원번호, 사원이름, 급여, 급여등급을 출력한다면?
SELECT emp_id,
emp_name,
salary,
case
when salary <= 3000000 then '초급'
when salary <= 4000000 then '중급'
else '고급'
END AS '급여등급'
FROM employee;
-- 복수행(그룹) 함수
-- 여러 행의 결과를 입력으로 하여 하나의 결과를 반환하는 함수. n개 입력에 대한 하나의 결과를 리턴하는 함수
-- 사원수 확인 : count()
SELECT COUNT(*)
FROM employee;
SELECT COUNT(IFNULL(bonus_pct, 0))
FROM employee;
-- 최저급여 확인 : min()
SELECT MIN(salary), emp_name -- 잘못된 결과 출력
FROM employee;
-- 급여총합, 평균
SELECT SUM(salary),
AVG(salary)
FROM employee;
'한화시스템 BEYOND SW캠프 > TIL' 카테고리의 다른 글
[2주차] 24.01.16 화요일 (0) | 2024.01.16 |
---|---|
[2주차] 24.01.15 월요일 (1) | 2024.01.15 |
[1주차] 24.01.11 목요일 (0) | 2024.01.11 |
[1주차] 24.01.10 수요일 (0) | 2024.01.10 |
[1주차] 24.01.09 화요일 (1) | 2024.01.09 |