쿼리문에서 키워드
및 사용자 지정 식별자
모두 항상 소문자를 사용한다
select empno, ename
from emp;
많은 해법에서 '인라인 뷰(inline view)' 또는 FROM
절의 서브쿼리를 사용한다
ANSI SQL 표준
에 따르면 이러한 뷰에 테이블 별칭을 지정해야 한다
따라서 'X' 및 'Y'와 같은 별칭을 사용하여 인라인 뷰에서 결과셋을 식별한다
select job, sal
from (select job, max(sal) sal
from emp
group by job) x;
마지막 괄호 뒤에 문자 'x'는 FROM
절의 하위 쿼리에 의해 반환되는 '테이블 명'을 뜻한다단, Oracle은 이러한 별칭을 지정하지 않고도 사용할 수 있다
CONCAT
열 값을 이어 붙일 수 있도록 해주는 내장 함수이다
'이름'의 급여는 'X원'입니다
라는 결과셋을 반환하겠다select concat(ename,'\'s salary is ', sal) as message
from emp;
>>
+-------------------------+
| message |
+-------------------------+
| SMITH's salary is 800 |
| ALLEN's salary is 1600 |
| WARD's salary is 1250 |
| JONES's salary is 2975 |
| MARTIN's salary is 1250 |
| BLAKE's salary is 2850 |
| CLARK's salary is 2450 |
| SCOTT's salary is 3000 |
| KING's salary is 5000 |
| TURNER's salary is 1500 |
| ADAMS's salary is 1100 |
| JAMES's salary is 950 |
| FORD's salary is 3000 |
| MILLER's salary is 1300 |
+-------------------------+
\
(백슬래시)가 SQL에서도 그대로 쓰일 수 있는 것 또한 확인되었다CASE WEHN ... THEN ... END (+AS X)
일반적인 언어에서의 if
문을 SQL에서도 쓸 수 있다는 것을 배웠다.
select ename,
case when job = 'salesman' then 'target'
else 'non-target'
end as Search_target
from emp;
>>
+--------+---------------+
| ename | Search_target |
+--------+---------------+
| SMITH | non-target |
| ALLEN | target |
| WARD | target |
| JONES | non-target |
| MARTIN | target |
| BLAKE | non-target |
| CLARK | non-target |
| SCOTT | non-target |
| KING | non-target |
| TURNER | target |
| ADAMS | non-target |
| JAMES | non-target |
| FORD | non-target |
| MILLER | non-target |
+--------+---------------+
CASE WHEN
이 작동되는 것을 확인했다MariaDB에서는 RAND()
라는 내장함수를 사용하여 난수를 생성한다
LIMIT
를 사용하여 출력되는 row의 개수를 조절할 수 있다
FETCH FIRST n ROWS ONLY
도 출력되는 row의 개수를 조절하는 데에 사용할 수 있다
ORDER BY
와 함께 사용한다
'emp' 테이블에서 무작위 7개의 행을 반환해보겠다
select * from emp
order by rand() limit 7
>>
+-------+--------+----------+------+------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+----------+------+------------+------+------+--------+
| 7499 | ALLEN | SALESMAN | 7698 | 2006-02-20 | 1600 | 300 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 2006-05-01 | 2850 | NULL | 30 |
| 7844 | TURNER | SALESMAN | 7698 | 2006-09-08 | 1500 | 0 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 2006-02-22 | 1250 | 500 | 30 |
| 7788 | SCOTT | ANALYST | 7566 | 2007-12-09 | 3000 | NULL | 20 |
| 7902 | FORD | ANALYST | 7566 | 2006-12-03 | 3000 | NULL | 20 |
| 7566 | JONES | MANAGER | 7839 | 2006-04-02 | 2975 | NULL | 20 |
+-------+--------+----------+------+------------+------+------+--------+
select * from emp
order by rand() fetch first 7 rows only
>>
+-------+--------+----------+------+------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+----------+------+------------+------+------+--------+
| 7499 | ALLEN | SALESMAN | 7698 | 2006-02-20 | 1600 | 300 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 2006-05-01 | 2850 | NULL | 30 |
| 7566 | JONES | MANAGER | 7839 | 2006-04-02 | 2975 | NULL | 20 |
| 7902 | FORD | ANALYST | 7566 | 2006-12-03 | 3000 | NULL | 20 |
| 7788 | SCOTT | ANALYST | 7566 | 2007-12-09 | 3000 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 2007-01-23 | 1300 | NULL | 10 |
| 7900 | JAMES | CLERK | 7698 | 2006-12-03 | 950 | 0 | 30 |
+-------+--------+----------+------+------------+------+------+--------+
NULL
값 찾기NULL
인 모든 행을 찾으려고 한다IS NULL
을 사용한다select *
from emp
where comm is null
>>
+-------+--------+-----------+------+------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+-----------+------+------------+------+------+--------+
| 7369 | SMITH | CLERK | 7902 | 2005-12-17 | 800 | NULL | 20 |
| 7566 | JONES | MANAGER | 7839 | 2006-04-02 | 2975 | NULL | 20 |
| 7698 | BLAKE | MANAGER | 7839 | 2006-05-01 | 2850 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7698 | 2006-06-09 | 2450 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 2007-12-09 | 3000 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 2006-11-17 | 5000 | NULL | 10 |
| 7876 | ADAMS | CLERK | 7788 | 2008-01-12 | 1100 | NULL | 20 |
| 7902 | FORD | ANALYST | 7566 | 2006-12-03 | 3000 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 2007-01-23 | 1300 | NULL | 10 |
+-------+--------+-----------+------+------------+------+------+--------+
null
은 자기 자신을 포함하여 다른 무엇과도 비교할 수 없다null
여부의 판별에는 =
또는 !=
을 사용할 수 없음에 유의하자null
의 판별에는 반드시 IS NULL
을 사용하도록 한다IS NOT NULL
을 사용하여 주어진 열에서 NULL
이 없는 행을 찾을 수도 있다select *
from emp
where comm is not null
>>
+-------+--------+----------+------+------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+----------+------+------------+------+------+--------+
| 7499 | ALLEN | SALESMAN | 7698 | 2006-02-20 | 1600 | 300 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 2006-02-22 | 1250 | 500 | 30 |
| 7654 | MARTIN | SALESMAN | 7698 | 2006-09-28 | 1250 | 1400 | 30 |
| 7844 | TURNER | SALESMAN | 7698 | 2006-09-08 | 1500 | 0 | 30 |
| 7900 | JAMES | CLERK | 7698 | 2006-12-03 | 950 | 0 | 30 |
+-------+--------+----------+------+------------+------+------+--------+
IS NOT NULL
은 말 그대로 NULL
값이 아닌 것 즉, 값을 가진 행만 확인하여 반환한다NULL
값을 실젯값으로 변환하기NULL
이 포함된 '행'에서 해당 NULL
대신 NULL이 아닌 값
을 반환하려고 한다COALESCE
함수를 사용하여 NULL
값을 실젯값으로 대체한다select coalesce(comm, 0)
from emp
>>
+-------------------+
| coalesce(comm, 0) |
+-------------------+
| 0 |
| 300 |
| 500 |
| 0 |
| 1400 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
+-------------------+
# aliase를 붙여보았다
select coalesce(comm, 'is null') as comm_is_null
from emp
>>
+--------------+
| comm_is_null |
+--------------+
| is null |
| 300 |
| 500 |
| is null |
| 1400 |
| is null |
| is null |
| is null |
| is null |
| 0 |
| is null |
| 0 |
| is null |
| is null |
+--------------+
COALESCE
함수는 하나 이상의 값을 인수(argument)
로 사용한다
이 함수는 목록에서 NULL
값이 아닌 값을 반환한다 (?)
NULL
에 관한 작업을 수행할 때, 각 DBMS에서 제공하는 내장함수를 활용하는 것이 가장 좋다
COALESCE
함수는 모든 DBMS에서 작동하며 CASE
또한 그러하다
select case
when comm is not null then comm
else 'is null'
end as 'is comm null?'
from emp;
>>
+---------------+
| is comm null? |
+---------------+
| is null |
| 300 |
| 500 |
| is null |
| 1400 |
| is null |
| is null |
| is null |
| is null |
| 0 |
| is null |
| 0 |
| is null |
| is null |
+---------------+
CASE WHEN THEN END
도 조건에 따라 COALESCE
와 동일하게 작동함을 볼 수 있다LIKE
연산자를 SQL 와일드카드 문자 중 하나인 %
연산자와 함께 사용한다select ename, job
from emp
where detpno in (10, 20)
and (ename like '%I%' or job like '%ER')
>>
+--------+-----------+
| ename | job |
+--------+-----------+
| SMITH | CLERK |
| JONES | MANAGER |
| CLARK | MANAGER |
| KING | PRESIDENT |
| MILLER | CLERK |
+--------+-----------+
%
연산자는 LIKE
패턴 일치 연산에 쓰일 때, 모든 문자 시퀀스와 일치한다
즉, %
연산자는 다른 모든 문자를 대신한다는 뜻이다
'i'를 %
연산자로 감싸면 'i'의 앞뒤로 존재하는 모든 문자를 %
로 대체하여 검색하겠다는 의미가 된다
%
연산자가 공백
도 포함하는지를 알아보겠다
첫 글자가 'i'로 시작하는 데이터를 하나 삽입해둘 것이다
insert into sqlcook.emp
values(7777, 'IREN', 'TESTER', 0000, '2022-07-03', 9000, 9000, 10)
select * from emp;
>>
+-------+--------+-----------+------+------------+------+------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+--------+-----------+------+------------+------+------+--------+
| 7369 | SMITH | CLERK | 7902 | 2005-12-17 | 800 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 2006-02-20 | 1600 | 300 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 2006-02-22 | 1250 | 500 | 30 |
| 7566 | JONES | MANAGER | 7839 | 2006-04-02 | 2975 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 2006-09-28 | 1250 | 1400 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 2006-05-01 | 2850 | NULL | 30 |
| 7777 | IREN | TESTER | 0 | 2022-07-03 | 9000 | 9000 | 10 |
| 7782 | CLARK | MANAGER | 7698 | 2006-06-09 | 2450 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 2007-12-09 | 3000 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 2006-11-17 | 5000 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 2006-09-08 | 1500 | 0 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 2008-01-12 | 1100 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 2006-12-03 | 950 | 0 | 30 |
| 7902 | FORD | ANALYST | 7566 | 2006-12-03 | 3000 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 2007-01-23 | 1300 | NULL | 10 |
+-------+--------+-----------+------+------------+------+------+--------+
중간 위치에 '7777, IREN...'으로 들어간 데이터를 볼 수 있다.
LIKE '%i%'
가 'i'로 시작하는 자료를 검색할까?%
가 공백
을 대체할까?select ename
from emp
where ename like '%i%'
>>
+--------+
| ename |
+--------+
| SMITH |
| MARTIN |
| IREN |
| KING |
| MILLER |
+--------+
select ename as 'name start with "i"'
from emp
where ename like 'i%'
>>
+---------------------+
| name start with "i" |
+---------------------+
| IREN |
+---------------------+
%
를 빼고 'i'로 시작해주면 된다''
와 ""
의 사용도 다른 언어에서와 동일하게 작동한다는 것도 확인했다NULL
에 관한 작업NULL
에 관한 작업은 IS NULL
, IS NOT NULL
을 사용한다COALESCE
는 NULL
에 대한 CASE WHEN THEN END
작업을 간소화해놓았다NULL
에 관한 작업이 많은데 이 모든 작업을 CASE WHEN THEN END
로 처리하려면LIKE
와 %
as
를 써주는 습관을 들이면 더 좋을 것 같다