SQL (1)
1. SELECT
-- 실행순서: FROM 절 -> SELECT 절
SELECT fieldnames
FROM tablename;
-- field의 가공처리
SELECT empno, ename, sal+100
FROM scott_emp;
-- field alias
SELECT empno, ename, mgr manager FROM scott_emp;
SELECT empno, ename, mgr as manager FROM scott_emp;
SELECT empno, ename, mgr as 'my manager' FROM scott_emp;
-- 중복 제거: distinct
SELECT distinct job
FROM scott_emp;
2. 확장 문법
2.1. 정렬 기능: ORDER BY
-- 실행순서: FROM 절 -> SELECT 절 -> ORDER BY 절
-- **Note: 정렬 기능은 항상 제일 마지막에**
SELECT fieldnames
FROM tablename
ORDER BY fieldnames;
-- 급여가 많은 순으로 이름, 급여, 부서코드를 조회
SELECT ename, sal, deptno
FROM scott_emp
ORDER BY sal DESC;
-- 부서별로 급여가 적은 순으로 이름, 급여, 부서코드 조회
SELECT ename, sal, deptno
FROM scott_emp
ORDER BY deptno, sal;
2.2. 조건 기능 (레코드 필터링): WHERE
-- 실행순서: FROM 절 -> WHERE 절 -> SELECT 절
SELECT fieldnames
FROM tablename
WHERE blah blah
-- 급여가 3000$ 이상인 직원의 사번, 이름, 급여를 조회
SELECT empno, ename, sal
FROM scott_emp
WHERE sal >= 3000;
-- 업무가 manager인 직원의 이름, 부서, 업무, 급여 조회
SELECT empno, ename, sal
FROM scott_emp
WHERE job = 'manager';
-- 부서가 20이고 업무가 analyst인 직원의 이름, 부서, 업무, 급여 조회
SELECT ename, deptno, job, sal
FROM scott_emp
WHERE deptno = 20 AND job = 'Analyst';
-- 급여가 1500 이상 2500 미만을 받는 직원의 이름, 부서, 업무 급여를 조회 (단, 급여가 많은 순으로 조회)
SELECT ename, deptno, job, sal
FROM scott_emp
WHERE sal >= 1500 AND sal <= 2000
ORDER BY sal DESC;
-- !!Note: BETWEEN AND는 '이상, 이하' 일 때만 쓸 수 있음
SELECT ename, deptno, job, sal
FROM scott_emp
WHERE sal BETWEEN 1500 AND 2000;
-- 업무가 clerk, salesman, analyst인 직원의 이름, 부서, 업무, 급여 조회
SELECT ename, deptno, job, sal
FROM scott_emp
WHERE job = 'clerk' OR job = 'salesman' OR job = 'analyst';
-- !!Note: IN은 'OR 조건' 일 때만 쓸 수 있음
SELECT ename, deptno, job, sal
FROM scott_emp
WHERE job IN ('clerk', 'salesman', 'analyst');
-- 1982/01/01 이후에 입사한 직원의 이름, 업무, 입사일자 조회
-- Note: SQL에서 날짜는 문자열 형식, 날짜형식만 유지하면 구분자는 상관없음
SELECT ename, job, hiredate
FROM scott_emp
WHERE hiredate > '1982-01-01';
WHERE hiredate > '1982/01/01';
WHERE hiredate > '1982,01,01';
-- 커미션이 없는 직원의 이름, 부서, 업무, 급여, 커미션 조회
SELECT ename, empno, job, sal, comm
FROM scott_emp
WHERE comm IS null;
-- 커미션이 있는 직원
SELECT ename, empno, job, sal, comm
FROM scott_emp
WHERE comm IS NOT null;
SELECT ename, empno, job, sal, comm
FROM scott_emp
WHERE comm >= 0;
2.3. Like 연산자
- % : 0개 이상의 문자 대체
- _ : 1개 문자 대체
- 예시: beau% - beau, beaut, beauti, ..
- 예시: beau__ - beauab, beauti, beaufl ..
-- 이름이 s로 끝나는 직원의 이름, 업무, 급여를 조회
SELECT ename, job, sal
FROM scott_emp
WHERE ename like '%s';
+-------+---------+------+
| ename | job | sal |
+-------+---------+------+
| JONES | MANAGER | 2975 |
| ADAMS | CLERK | 1100 |
| JAMES | CLERK | 950 |
+-------+---------+------+
2.4. GROUP BY & HAVING 조건
- Group by 절: 특정 컬럼 값을 기준으로 그룹화
- Having 절: 그룹으로 묶은 뒤, 조건이 있는 경우
-- 부서별로 급여 평균, 최저 급여 조회 (급여 평균이 높은 순으로)
-- 실행순서: FROM -> GROUP BY ->SELECT -> ORDER BY
SELECT deptno, round(avg(sal)), round(min(sal))
FROM scott_emp
GROUP BY deptno
ORDER BY avg(sal) DESC;
+--------+-----------------+-----------------+
| deptno | round(avg(sal)) | round(min(sal)) |
+--------+-----------------+-----------------+
| 10 | 2917 | 1300 |
| 20 | 2175 | 800 |
| 30 | 1567 | 950 |
+--------+-----------------+-----------------+
-- 전체 급여의 합계가 5000을 초과하는 업무에 대해서 급여 합계 조회 (deptno로 정렬)
-- 실행순서: FROM -> GROUP BY -> HAVING -> SELECT -> ORDER BY
SELECT job, sum(sal)
FROM scott_emp /* WHERE sum(sal) > 5000 오류발생 */
GROUP BY job
HAVING sum(sal) > 5000
ORDER BY deptno;
+----------+----------+
| job | sum(sal) |
+----------+----------+
| ANALYST | 6000 |
| MANAGER | 8275 |
| SALESMAN | 5600 |
+----------+----------+
-- 전체 급여의 합계가 5000을 초과하는 업무에 대해서 급여 합계 조회 (단, salesman 제외)
SELECT job, sum(sal)
FROM scott_emp
GROUP BY job
HAVING sum(sal) > 5000 AND job <> 'salesman';
-- 성능 더 좋음
SELECT job, sum(sal)
FROM scott_emp
WHERE job <> 'salesman'
GROUP BY job
HAVING sum(sal) > 5000;
+---------+----------+
| job | sum(sal) |
+---------+----------+
| ANALYST | 6000 |
| MANAGER | 8275 |
+---------+----------+
3. 함수
3.1. Single-Row Function (단일행 함수)
String Function:
- ASCII( ), CHAR()
- LENGTH()
- INSTR()
- LEFT(), RIGHT(), SUBSTR(), SUBSTRING()
SELECT ASCII('a');
--> 97
SELECT CHAR(98);
--> b
SELECT LENGTH(ename) FROM scott_emp;
-- Note: SQL의 문자열 index는 1부터 시작
SELECT INSTR('foobarbar', 'bar');
--> 4
SELECT INSTR('foobarbar', 'love');
--> 0
SELECT LEFT('abcdefg', 3);
--> abc
SELECT RIGHT('abcdefg', 4);
--> defg
SELECT SUBSTRING('i lovee SQL', 3);
--> lovee SQL
SELECT SUBSTRING('i lovee SQL', 3, 4);
--> love
SELECT SUBSTRING('i lovee sql', -3);
--> sql
SELECT SUBSTRING('i lovee sql', -9, 5);
--> lovee
Numeric Function
- CEIL(), FLOOR(), ROUND(), TRUNCATE()
- MOD()
- RAND()
SELECT CEIL(1.23);
--> 2
SELECT FLOOR(1.73);
--> 1
SELECT ROUND(1.23), ROUND(1.73);
--> 1 | 2
SELECT ROUND(1.298, 1);
--> 1.3
SELECT TRUNCATE(1.73, 0);
--> 1
Date Function
-- NOW(), SYSDATE(), CURDATE(), CURTIME()
SELECT NOW();
-- YEAR(), MONTH(), DAYOFMONTH()
SELECT YEAR(NOW()), MONTH(NOW());
-- DAYOFWEEK(): 1-일요일, WEEKDAY(): 0-월요일
SELECT DAYOFWEEK(NOW()), WEEKDAY(NOW());
-- DAOFYEAR(): 1년 중 며칠이 지났는지 알려줌
SELECT DAYOFYEAR(NOW());
-- DATE_ADD(), DATE_SUB()
SELECT DATE_ADD(NOW(), interval 5 YEAR), DATE_ADD(NOW(), interval 5 DAY);
3.2. Aggregation Function
SUM(), AVG(), COUNT(), MAX(), MIN()
3.3. 기타
CONVERT(), CASE(), COALESCE()
-- CONVERT()
SELECT CONVERT('2019-5-1', DATE);
SELECT CONVERT(150, CHAR);
SELECT CONVERT('14:06:10', TIME);
-- CASE()
-- 업무가 salesman이면 'yes' 이라고하고, 그 외 업무는 'no' 라고 조회
SELECT ename, job, comm,
CASE
WHEN job = 'salesman' THEN 'yes'
ELSE 'no'
END iscomm
FROM scott_emp;
+--------+-----------+--------+
| ename | comm | iscomm |
+--------+-----------+--------+
| SMITH | CLERK | no |
| ALLEN | SALESMAN | yes |
| WARD | SALESMAN | yes |
| JONES | MANAGER | no |
| MARTIN | SALESMAN | yes |
| BLAKE | MANAGER | no |
| CLARK | MANAGER | no |
| SCOTT | ANALYST | no |
| KING | PRESIDENT | no |
| TURNER | SALESMAN | yes |
| ADAMS | CLERK | no |
| JAMES | CLERK | no |
| FORD | ANALYST | no |
| MILLER | CLERK | no |
+--------+-----------+--------+
-- COALESCE()
-- 현재 직원들의 총 급여를 조회
SELECT empno, ename, sal, comm, (sal + comm) as total FROM scott_emp;
--null값 처리
SELECT empno, ename, sal, comm,
(sal + COALESCE(comm, 0)) as total
FROM scott_emp;
+-------+--------+------+------+-------+
| empno | ename | sal | comm | total |
+-------+--------+------+------+-------+
| 7369 | SMITH | 800 | NULL | 800 |
| 7499 | ALLEN | 1600 | 300 | 1900 |
| 7521 | WARD | 1250 | 500 | 1750 |
| 7566 | JONES | 2975 | NULL | 2975 |
| 7654 | MARTIN | 1250 | 1400 | 2650 |
| 7698 | BLAKE | 2850 | NULL | 2850 |
| 7782 | CLARK | 2450 | NULL | 2450 |
| 7788 | SCOTT | 3000 | NULL | 3000 |
| 7839 | KING | 5000 | NULL | 5000 |
| 7844 | TURNER | 1500 | 0 | 1500 |
| 7876 | ADAMS | 1100 | NULL | 1100 |
| 7900 | JAMES | 950 | NULL | 950 |
| 7902 | FORD | 3000 | NULL | 3000 |
| 7934 | MILLER | 1300 | NULL | 1300 |
+-------+--------+------+------+-------+