필요한 데이터만 출력하는 WHERE절
WHERE절은 SELECT문으로 데이터를 조회할 때 특정 조건을 기준으로 원하는 행을 출력하는데 사용된다. 그리고 여러 연산자를 함께 사용하면 더욱 세밀하게 데이터 검색이 가능하다.
SELECT*
FROM EMP
WHERE DEPTNO = 30;
WHERE절에 작성한 DEPTNO=30은 'EMP테이블에서 부서 번호 값이 30인 행만 조회하라'는 뜻이다. 즉 부서번호 30인 사람들의 데이터만 출력한 것이다.
이렇게 WHERE절은 많은 데이터 중에서 어떤 조건에 일치하는 행만을 골라내어 조회하는데 사용된다. WHERE절을 사용한 SELECT문의 기본형식은 다음과 같다.
SELECT [조회할 열1 이름], [열2 이름], ... , [열N 이름]
FROM [조회할 테이블 이름]
WHERE [조회할 행을 선별하기 위한 조건식];
키워드 : 필수요소 : 선택요소 : 설명
WHERE : 조건식 : - : 조회 조건 지정
WHERE절이 포함된 SELECT문을 실행하면 조회할 테이블의 각 행에 WHERE절의 조건식을 대입하여 결과가 '참'인 경우에만 출력된다. 이 논리적 의미의 '참'을 true로, '거짓'인 경우를 false로 표현한다.
즉 위의 예제에서는 EMP테이블의 각 행에 부서 번호 열 값을 검사한 후 결과 값이 true인 데이터만 출력이된다.
여러 개의 조건식을 사용하는 AND, OR 연산자
WHERE절에서는 조건식을 여러개 지정이 가능한데, 이 때 사용하는 것이 바로 논리연산자 AND, OR이다.
SELECT *
FROM EMP
WHERE DEPTNO = 30
AND JOB = 'SALESMAN';
- WHERE절에서 비교하는 데이터가 문자열일 경우에 작은따옴표로 묶어준다. 앞뒤에 공백이 있으면 공백도 문자로 인식하기 때문에 주의해야 한다.
SQL문에 사용하는 기본 형식은 대/소문자를 구별하지 않고 사용할 수 있지만 테이블 안에 들어있는 문자 또는 문자열 데이터는 대/소 문자를 구별한다.
AND연산자 표에서 확인할 수 있듯이 AND연산자를 사용한 위의 예제의 SELECT문은 DEPTNO=30 조건식과 JOB='SALESMAN' 조건식의 결과 값이 모두 true인 행만 출력을 한다.
SELECT *
FROM EMP
WHERE DEPTNO = 30
OR JOB = 'CLERK';
위의 결과를 살펴보면 AND연산자를 사용했을 떄와 부서번호 값이 30인 행과 직업이 CLERK인 행 모두 출력되는 것을 알 수 있다.
따라서 OR연산자를 사용한 SELECT문의 결과는 부서 번호 열 값이 30이거나 직업 열 값이 CLERK인 사원을 모두 출력한 것이다.
WHERE절 조건식의 개수
SELECT *
FROM EMP
WHERE [조건식 1]
AND [조건식 2]
OR [조건식 3]
...
AND [조건식 N]
위와 같이 WHERE절에 사용할 수 있는 조건식의 개수는 사실상 제한이 없다고 봐도 무방하다. 조건식을 두 개 이상 사용할 경우에도 각 조건식 사이에 AND 또는 OR연산자를 추가하여 사용할 수 있다.
연산자의 종류와 활용방법 알아보기
산술연산자
더하기 , 빼기 같은 수치 연산에 사용하는 산술 연산자이다. +,-,*,/ 을 이용한다.
다음의 SELECT문은 EMP 테이블에서 급여 열에 12를 곱한 값이 36000인 행을 출력하는 SQL문이다.
SELECT *
FROM EMP
WHERE SAL* 12 = 36000;
이와 같이 WHERE절의 조건식에도 산술 연산자를 사용할 수 있다.
비교연산자
대소 비교연산자
비교 연산자는 SQL문을 작성할 때 자주 사용하는 연산자로 연산자 앞뒤에 있는 데이터 값을 비교하는데 사용한다.
SELECT *
FROM EMP
WHERE SAL >= 3000;
이 외에도 초과,미만, 이하 여부를 비교하는 대소 비교 연산자가 있다.
, >=, <, <=
대소 비교 연산자는 비교 대상인 데이터가 숫자가 아닌 문자열일 때도 사용 가능하다.
SELECT *
FROM EMP
WHERE ENAME >= 'F';
문자열을 비교할 때 영어 사전 처럼 알파벳 순서로 문자열의 '대소'를 비교한다. 조건식 ENAME≥'F'는 ENAME 열 값의 첫 문자와 대문자 F를 비교했을 때 알파벳 순서상 F와 같거나, F보다 뒤에 있는 문자열을 출력하라는 의미이다.
SELECT *
FROM EMP
WHERE ENAME <= 'FORZ';
그리고 ENAME≤ 'FORZ'는 ENAME의 열 값이 FORZ를 포함한 문자열보다 알파벳 순서대로 앞에 있는 행을 출력하라는 의미이다. 예를 들어 ENAME에 'FIND'문자열이 있다고 가정해보자.
FIND의 첫 문자는 F로 FORZ와 같지만, 두 번째 문자 I가 FORZ의 O보다 알파벳 순서상 빠르므로 WHERE절의 조건식에 해당하는 값이 된다.
등가 비교 연산자
연산자 양쪽 항목이 같은 값인지 검사하는 연산자가 등가 비교 연산자이다.
지금까지 WHERE절의 조건식에서 사용한 =기호가 등가 비교 연산자이다.
등가 비교 연산자는 연산자의 양쪽 항목이 같으면 true가 반환된다. 이와 반대로 연산자 양쪽 값이 다를 경우 true를 반환하는 연산자도 있다.
A = B : A값이 B값과 같을 경우 true, 다를 경우 false 반환
A != B
A <> B
A ^=b
위의 세개연산자는 다 같은 방식이다. A값과 B값이 다를 경우 true, 같을 경우 false를 반환한다.
SELECT *
FROM EMP
WHERE SAL != 3000;
SELECT *
FROM EMP
WHERE SAL <> 3000;
SELECT *
FROM EMP
WHERE SAL ^= 3000;
- SAL 열 값이 3000인 결과만 출력에서 제외된다
논리 부정 연산자
비교 연산자는 아니지만 위와 같은 결과를 출력하기 위해 사용할 수 있는 연산자가 하나 더 존재한다.
그것은 바로 논리 부정 연산자(NOT 연산자)이다.
만약 A값이 true일 경우 논리 부정 연산자의 결과 값은 false가 된다.
SELECT *
FROM EMP
WHERE NOT SAL = 3000;
위의 예제를 NOT연산자로 표현한 것이다.
보통 NOT연사자를 IN, BETWEEN, IS NULL 연산자와 함께 복합적으로 사용하는 경우가 많고, 대소/등가 비교 연산자에 직접 사용하는 경우는 별로 없다.
하지만 여러개의 조건식이 AND, OR로 묶여 있는 상태에서 정반대 결과를 얻고자 할 때에는 유용하게 사용할 수 있다.
IN연산자
=기호는 WHERE조건식에서 특정 열 데이터 값만을 조회하고자 할 때 사용한다.
SELECT *
FROM EMP
WHERE JOB = 'MANAGER'
OR JOB ='SALESMAN'
OR JOB = 'CLERK';
위 예제는 직책 열이 SALESMAN이거나 MANAGER 또는 CLERK 중 하나인 데이터를 조회하는 예제이다.
위와 같이 출력하고 싶은 열의 조건이 여러 가지 일때 OR연산자로 여러 조건식을 묶어주는것도 하나의 방법이지만, 조건이 늘어날 수록 조건식을 많이 작성을 해야한다.
이때 IN 연산자를 사용하면 특정 열에 해당하는 조건을 여러 개 지정할 수 있다. IN연산자의 기본형식은 다음과 같다.
SELECT [조회할 열1 이름], [열2 이름], ..., [열N 이름]
FROM [조회할 테이블 이름]
WHERE 열 이름 IN (데이터1,데이터2,...,데이터N);
키워드 : 필수요소 : 선택요소 : 설명
IN : 열 이름, 조회할 열의 데이터 목록 : - : 특정열에 포함된 데이터를 여러 개 조회할 때 활용
위의 예제를 IN연사자로 표현하면 다음과 같이 작성이 가능하다.
SELECT *
FROM EMP
WHERE JOB IN ('MANAGER', 'SALESMAN', 'CLERK');
이번에는 위와 반대의 경우를 생각해보자. 직책 열 값이 MANAGER도 아니고, SALESMAN,CLERK도 아닌 데이터를 찾을 때 앞에서 배운 등가 비교 연산자와 AND연산자를 사용하여 세 값이 모두 아닌 데이터를 찾기 위해 SELECT문을 다음과 같이 작성할 수 있다.
SELECT *
FROM EMP
WHERE JOB != 'MANAGER'
AND JOB <> 'SALESMAN'
AND JOB ^= 'CLERK';
위의 예제와 출력결과는 같지만 , IN 연산자 앞에 논리 부정 연산자 NOT을 사용하면 좀 더 간단하게 반대 경우를 조회할 수 있다.
SELECT *
FROM EMP
WHERE JOB NOT IN('MANAGER', 'SALESMAN', 'CLERK');
BETWEEN A AND B 연산자
급여 열 값이 2000이상 3000이하, 즉 급여가 2000~3000인 사원 데이터를 조회해야 한다고 가장하자.
이 SELECT문을 작성할 때 WHERE절 조건에 급여 열 값이 2000이상인 조건과 3000이하인 조건이 필요하다. 앞에서 배운 대소 비교 연산자와 AND연산자를 사용하면 다음과 같이 SELECT문을 만들 수 있다.
SELECT *
FROM EMP
WHERE SAL >= 2000
AND SAL <= 3000;
위와 같이 특정 열 값의 최소,최고 범위를 지정하여 해당 범위 내의 데이터만 조회할 경우에 대소 비교 연산자 대신 BETWEEN A AND B 연산자를 사용하면 더 간단하게 표현할 수 있다.
SELECT [조회할 열1 이름], [열2 이름], .... [열N이름]
FROM [조회할 테이블 이름]
WHERE 열 이름 BETWEEN 최소값 AND 최댓값;
키워드 : 필수 요소 : 선택 요소 : 설명
BETWEEN A AND B : 열 이름, 최소값, 최댓값:-: 일정 범위 내의 데이터를 조회할 때 사용
SELECT *
FROM EMP
WHERE SAL BETWEEN 2000 AND 3000;
위의 예제를 BETWEEN 연산자를 사용하여 작성한 것이다. 결과는 위의 예제와 같다.
IN연산자와 마찬가지로 NOT연산자를 앞에 붙이면 SAL 열이 2000~3000사이 외의 값을 가진 데이터만 출력할 수 있다.
SELECT *
FROM EMP
WHERE SAL NOT BETWEEN 2000 AND 3000;
LIKE 연산자와 와일드 카드
LIKE연산자는 이메일이나 게시판 제목 또는 내용 검색 기능처럼 일부 문자열이 포함된 데이터를 조회할 때 사용한다.
SELECT *
FROM EMP
WHERE ENAME LIKE 'S%';
위 예제에서 ENAME LIKE 'S%' 조건식은 ENAME 열 값이 대문자 S로 시작하는 데이터를 조회하라는 뜻이다. 이 조건식에서 사용한 %기호를 와일드 카드(wild card)라고 한다.
와일드 카드는 특정 문자 또는 문자열을 대체하거나 문자열 데이터의 패턴을 표기하는 특수 문자이다. LIKE연산자와 함께 사용할 수 있는 와일드 카드는 _와 %이다.
_ : 어떤 값이든 상관없이 한 개의 문자 데이터를 의미
% : 길이와 상관없이(문자 없는 경우도 포함) 모든 문자 데이터를 의미
앞에서 사용한 LIKE S%는 시작 문자가 S면 그 뒤에 어떤 문자 몇 개가 오든 상관없이 LIKE연산자를 이사용한 조건식의 결과 값은 true가 된다. 만약 사원 이름이 두 번째 글자가 L인 사원 데이터를 조회하고 싶다면 다음과 같이 LIKE연산자에 와일드 카드를 활용할 수 있다.
SELECT *
FROM EMP
WHERE ENAME LIKE '_L%';
-L%의 의미는 데이터의 첫번째 문자가 와일드카드(_)이기 때문에 문자 종료와 상관없이 L앞에는 단 하나의 문자가 오는 것을 의미한다. 그리고 두번째 글자가 L이고 L이후 와일드 카드(%)를 지정하였기 때문에 L뒤에 올 문자는 어떤 종료의 문자가 몇 개가 오든지 상관없다.
즉 사원 이름 중에 두번째 문자가 L인 데이터를 가리키게 된다. 위 예제의 결과를 살펴보면 EMP테이블에서 사원 이름 열의 데이터 중 두번째 문자가 'L'인 ALLEN, BLAKE, CLARK데이터가 조회되었음을 확인 할 수 있다.
어떤 단어가 포함된 제목 또는 본문 검색과 같은 기능을 구현할 때는 원하는 문자열 앞뒤 모두 와일드카드(%)를 붙여줄 수 있다.
SELECT *
FROM EMP
WHERE ENAME LIKE '%AM%';
위의 결과를 살펴보면 사원 이름의 열 값에 AM이라는 단어가 포함되어 있고, AM 앞뒤에 몇 글자가 오건 어떤 종류의 문자가 오건 상관없이 사원 데이터가 출력되는 것을 알 수 있다.
만약 위와 반대로 AM이라는 단어가 포함된 데이터를 제외한 결과를 얻고자 할 경우에는 다음과 같이 LIKE연산자에 NOT을 붙여줄 수 있다.
SELECT *
FROM EMP
WHERE ENAME NOT LIKE '%AM%';
와일드 카드 문자가 데이터 일부일 경우
데이터에 와일드 카드 기호로 사용되는 _나 %문자가 데이터로 포함된 경우가 간혹 있다. 이 경우에 _문자나 %문자를 포함한 데이터를 조회하기 위해서 와일드 카드 문자를 쓰는 것은 애매해진다. 하지만 ESCAPE절을 사용하면 _, %를 와일드 카드 기호가 아닌 데이터로서의 문자로 다루는 것이 가능하다. 예를 들어 LIKE문을 사용하여 데이터 앞에 A_A 문자를 가지고 있는 데이터를 찾으려면 다음과 같이 SQL문을 작성하면 된다.
SELECT *
FROM SOME_TABLE
WHERE SOME_COLUMM LIKE 'A\_A%' EXCAPE '\';
A\_A%에서 \문자 바로 뒤에 있는 _는 와일드 카드 기호로서가 아닌 데이터에 포함된 문자로 인식하라는 의미이다. ESCAPE문자 \는 ESCAPE절에서 지정할 수 있다. 그리고 \외 다른 문자를 지정하여 사용할 수 있다.
IS NULL 연산자
IS NULL연산자를 살펴보기전에 NULL에 대해서 살펴보자.
NULL은 데이터베이스에서 중요한 의미가 있는 특수한 데이터 형식이다.
SELECT ENAME, SAL*12+COMM AS ANNSAL, COMM
FROM EMP;
위의 결과를 보면 SAL열에 12를 곱하고 추가 수당 열 값을 더한 결과는 나오는 경우도 있고 안나오는 경우도 있다. 결과가 나오지 않는 현상은 연산에 사용한 추가 수당 열 값이 비어있는 행에서만 나타난다.
이렇듯 NULL은 데이터 값이 완전히 '비어있는'상태를 말한다. 숫자 0은 값 0이 존재한다는 뜻이므로 NULL과 혼동하지 않도록 주의해야 한다. NULL의 의미를 예를 들어 설명하면 다음과 같다.
값이 존재하지 않음 , 해당사항없음, 노출할 수 없는 값, 확정되지 않은 값
따라서 NULL은 현재 무슨값인지 확정되지 않은 상태이거나 값 자체가 존재하지 않는 상태를 나타내는 데이터에 사용한다. 이 때문에 앞에서 살펴본 연산자는 대부분 연산 대상이 NULL일때 연산 자체가 무의미해지는 현상이 발생한다.
예를 들어 피연산자 값이 같은지 확인하는데 사용하는 등가 비교 연산자를 NULL에 대입한 다음 SELECT문을 실행해보자.
SELECT *
FROM EMP
WHERE COMM = NULL;
위의 결과로 추가 수당 열 값이 NULL인 행이 나와야 할것 같지만 실제로 출력되는 데이터는 없다. NULL은 산술 연산자와 비교연산자로 비교해도 결과 값이 NULL이다.
WHERE절은 조건식이 true인 행만 출력하는데 이처럼 연산 결과 값이 NULL이 되어버리면 조건식의 결과값이 false라도 true도 아니게 되므로 출력대상에서 제외된다. 따라서 지금까지 살펴본 연산자로는 특정 열의 데이터가 NULL인 경우를 구별해 낼 수 없다.
특정 열 또는 연산의 결과 값이 NULL인지 여부를 확인하려면 IS NULL연산자를 사용해야 한다.
위의 예제에서 SELECT문에서 본래 의도한 의미대로 추가 수당 열값이 NULL인 데이터를 출력하고 싶다면 다음과 같이 IS NULL연산자를 사용하면 된다.
SELECT *
FROM EMP
WHERE COMM IS NULL;
위 결과에서 알 수 있듯이 IS NULL연산자를 사용하면 추가 수당 열 값이 존재하지 않는 데이터만 출력된다.
반대의 경우, 즉 추가 수당 값이 NULL이 아닌 데이터만 조회하라면 IS NOT NULL을 사용하면 된다.
직속 상관의 사원번호 열에는 사원의 상급자 사원 번호가 담겨있다. KING은 최고 직급인 PRESIDENT이므로 직속상관이 존재하지 않는다. 그렇기 떄문에 직속상관 열 값이 NULL이다. 직송 상관 열이 NULL이 아닌 사원만 조회할 경우 다음과 같이 IS NOT NULL연산자를 사용하면 된다.
SELECT *
FROM EMP
WHERE MGR IS NOT NULL;
데이터가 NULL인지 아닌지를 확인하는 용도로만 사용하는 IS NULL과 IS NOT NULL연산자는 매우 자주 사용되므로 사용법을 꼭 기억해야 한다.
집합 연산자
관계형 데이터베이스 개념은 집합론에서 시작되었따. SQL문에서는 SELECT문을 통해 데이터를 조회한 결과를 하나의 집합과 같이 다룰 수 있는 집합 연산자를 사용할 수 있다. 그리고 두 개 이상의 SELECT문의 결과 값을 연결할 때 사용한다.
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10
UNION
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 20;
SELECT문은 지금까지 사용한 SELECT문과는 다른 형태를 띄고 있다.
두 개의 SELECT문 사이에 사용된 UNION연산자가 바로 집합 연산자이다. 이 연산자는 합집합을 의미하는 연산자이다. 결과 화면을 살펴보면 10번 부서에 근무하는 사원과 20번 부서에 근무하는 사원 정보가 합쳐져 출력된것을 알 수 있다.
여기에서 주의할 점은 집합 연산자로 두 개의 SELECT문의 결과값을 연결할 때와 각 SELECT문이 출력하려는 열 개수와 각 열의 자료형이 순서별로 일치해야 한다는 것이다.
만열 연결하려는 두 SELECT문의 열 개수와 자료형이 같다면 서로 다른 테이블에서 조회하거나 조회하는 열 이름이 다른 것은 문제가 되지 않는다. 다소 이상해보이지만 집합 연산자를 다음과 같이 사용이 가능하다.
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10
UNION
SELECT SAL, JOB, DEPTNO, SAL
FROM EMP
WHERE DEPTNO = 20;
EMPNO와 SAL열은 다른 열이지만 양쪽 다 숫자가 저장된 데이터이기 때문에 문제없이 연결되고 있다. 다만 최종 출력되는 열 이름은 먼저 작성한 SELECT문의 열 이름으로 표기가 된다.
UNION : 연결된 SELECT문의 결과값을 합집합으로 묶어준다. 결과 값의 중복은 제거
UNION ALL : 연결된 SELECT문의 결과 값을 합집합으로 묶어준다. 중복된 결과 값도 제거 없이 모두 출력된다.
MINUS : 먼저 작성한 SELECT문의 결과 값에서 다름 SELECT문의 결과 값을 차집합 처리한다. 먼저 작성한 SELECT문의 결과 값 중 다음 SELECT문에 존재하지 안흔 데이터만 출력된다.
INTERSECT : 먼저 작성한 SELECT문과 다음 SELECT문의 결과 값이 같은 데이터만 출력된다. 교집합과 같은 의미이다.
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10
UNION
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10;
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10
UNION ALL
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10;
UNION은 데이터 중복을 제거한 상태로 결과값을 출력하고 UNION ALL은 중복 데이터도 모두 출력한다. 둘 다 합집합을 의미하는 연산자이지만 결과 값이 달라지므로 사용할 때 주의해야 한다.
MINUS연산자는 차 집합을 의미하는데, 다음과 같이 두 SELECT문을 MINUS연산자로 묶어 주면 두 SELECT문의 결과 값이 같은 데이터는 제외하고, 첫번째 SELECT문의 결과 값이 출력된다.
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
MINUS
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10;
EMP 테이블 전체 행을 조회한 첫 번째 SELECT문의 결과에서 10번 부서에 있는 사원 데이터를 제외한 결과 값이 출력된다.
INTERSECT연산자는 교집합을 의미하므로 두 SELECT문의 결과 값이 같은 데이터만 출력된다.
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
INTERSECT
SELECT EMPNO, ENAME, SAL, DEPTNO
FROM EMP
WHERE DEPTNO = 10;
'Back-end' 카테고리의 다른 글
SQL 문법(1) (0) | 2021.07.11 |
---|---|
11 컬렉션 프레임웍(6) (0) | 2021.07.10 |
11 컬렉션 프레임웍(5) (0) | 2021.07.09 |
11 컬렉션 프레임웍(4) (0) | 2021.07.08 |
11 컬렉션 프레임웍(3) (0) | 2021.07.07 |