안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
WHERE 구문
- 지정한 테이블에서 행을 추려내기 위한 조건절
- 각 행마다 컬럼 값을 검사해서 true가 반환된 행은 결과 집합 포함, false가 반환된 행은 결과 집합에서 제외
※ null 값도 false처리 되므로 null 값들도 false → 결과 집합 포함 안됨
연산자 | 설명 |
= | 같다 |
!=, <>, ^= | 같지 않다 |
>, >=, <, <= | 크다, 크거나 같다, 작다, 작거나 같다 |
between a and b | a 이상 b 이하에 포함 여부 (이상~이하) |
like / not like | 문자열 패턴 비교 |
is null / is not null | null 값 여부 비교 |
in / not in | 비교 값 목록에 포함 여부 (기본적으로 or 연산) |
and | 좌항/우항의 논리 값이 모두 true인 경우, true 반환 / 나머지는 false |
or | 좌항/우항의 논리 값 중 하나라도 true인 경우, true 반환 / 나머지는 false |
not | 반전 (true를 false로, false를 true로) |
☞ 동등비교
사원 테이블에서 부서 코드가 D6인 사원 조회 (사원명, 부서코드)
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
dept_code = 'D6';
사원 테이블에서 부서 코드가 D6이면서 급여가 300만원 이상인 사원 조회 (사원명, 부서코드, 급여)
select
emp_name 사원명,
dept_code 부서코드,
salary 급여
from
employee
where
dept_code = 'D6' and salary >= 3000000;
직급 코드가 'J1'이 아닌 사원의 급여 등급을 중복 없이 출력
select distinct
sal_level
from
employee
where
job_code != 'J1'; -- job_code <> 'J1" / job_code ^= 'J1' 모두 가능
부서 코드가 지정되지 않은 사원 조회 (사원명, 부서코드)
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
dept_code is null;
-- dept_code = null; -- null과는 어떤 연산 불가!!
여기서 dept_code = null을 한다면 결과 값은 null 일 것이고, null은 false를 반환하기 때문에 데이터가 나오지 않을 것입니다.
null을 비교할 때는 반드시 is null, is not null을 이용!!
☞ between a and b 연산자
- 범위에 포함되면 true를 반환
- a (작은 값) 이상 b (큰 값) 이하
- 숫자형 / 날짜형 처리 가능
급여가 350만원 이상 600만원 이하인 사원 조회 (사원명, 급여)
select
emp_name 사원명,
salary 급여
from
employee
where
salary between 3500000 and 6000000;
-- salary >= 3500000 and salary <= 6000000; 로도 대체가능
급여가 350만원 미만 또는 600만원 초과인 사원 조회 (사원명, 급여)
select
emp_name 사원명,
salary 급여
from
employee
where
salary not between 3500000 and 6000000; -- not salary between ..~ 도 가능
-- salary < 3500000 or salary > 6000000; -- 로도 대체가능
* 날짜 범위 연산
입사일이 90년 1월 1일 ~ 01년 01월 01일 사원을 조회 (사원명, 입사일)
select
emp_name 사원명,
hire_date 입사일
from
employee
where
hire_date between '900101' and '010101'; -- 날짜포맷의 문자열을 사용하면 자동으로 날짜형으로 변환 처리
yyyy/mm/dd
yy/mm/dd
yyyy-mm-dd
yymmdd
날짜 포맷의 문자열을 사용하면 자동으로 날짜형으로 변환 처리 해줍니다.
☞ like / not like 문자열 패턴 비교 연산자
- 비교하는 값이 지정한 패턴을 만족하는 경우 true를 반환
다음의 와일드 카드를 지원합니다.
% | 0개 이상의 문자 |
_ | 문자 1개와 매칭 |
전씨 사원 조회
select
emp_name 사원명
from
employee
where
-- emp_name like '전%';
emp_name like '전__';
'전%'과 '전__'의 결과 값은 현재 동일하지만, '전%'와 '전__'의 차이는 분명하게 있습니다.
'전%' → '전' 다음 0글자 이상이 연결되는 경우. 전형돈(O), 전지연(O), 전(O), 전진(O), 전가라세(O)
'전__' → '전' 이후 _ 개수만큼 정확히 연결되는 경우. 전형돈(O), 전지연(O), 전(X), 전진(X), 전가라세(X)
현재 전씨 사원이 '전형돈', '전지연' 이기 때문에 동일한 결과가 출력됐을지라도 만일 사원명 중 '전진', '전가라세' 등이 있었다면 둘의 결과는 확연히 달랐을 것입니다.
이름에 '이'가 들어가는 사원을 모두 조회
select
emp_name 사원명
from
employee
where
emp_name like '%이%';
이메일의 '_' 앞 글자가 3자리인 사원 조회
select
emp_name 사원명,
email 이메일
from
employee
where
-- email like '____%'; 4글자 이상을 조회하게 됨
email like '___\_%' escape '\';
만일 '_' 앞에 3글자를 나타내기 위해 email like '____' 으로 하게 된다면,
시스템은 우리가 이메일의 '_'를 나타내는 마지막 '_'를 자리수를 표현하는 '_'로 인식하게 되어 4글자 이상의 이메일을 출력하게 됩니다.
escape 문자를 나타내기 위하여 해당 문자 앞에 escape문자를 지정해주고, 해당 문자가 escape이라는 표시를 해줍니다.
이 때, escape문자는 자유롭게 지정 가능하지만, 데이터에 포함되지 않은 문자여야겠죠!
email like '___#_%' escape '#';
email like '___^_%' escape '^';
--escape 문자는 자유롭게 지정 가능
☞ in 값 목록 포함 여부 연산자
- 제시한 값 목록에 포함 되어 있으면 true
※ null 값인 컬럼은 in 연산에도, not in 연산에도 포함 되지 않음
부서코드가 D6, D8인 사원 조회 (사원명, 부서코드)
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
-- dept_code = 'D6' or dept_code = 'D8'; 으로도 표현가능
dept_code in ('D6', 'D8');
부서코드가 D6, D8이 아닌 사원 조회 (사원명, 부서코드)
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
-- dept_code != 'D6' and dept_code != 'D8';
dept_code not in ('D6', 'D8');
☞ 연산자 우선 순위
① 산술연산 / 연결연산
② 비교연산
③ 논리연산 (not → and → or)
부서코드가 D5 또는 D9이면서 급여가 270만원 이상인 사원 조회
-- 틀린 답!
select
emp_name 사원명,
dept_code 부서코드,
salary 급여
from
employee
where
dept_code = 'D5' or dept_code = 'D9'
and
salary >= 2700000;
언뜻 보기에는 문제가 없는 로직일 수 있겠지만, 이렇게 하면 원하는 결과 값을 얻을 수 없습니다.
결과를 보면 급여가 270만원 이하인 사원들도 같이 출력 되는 것을 확인할 수 있습니다.
그 이유는 연산자 우선 순위 때문인데요.
논리 연산에서도 not - and - or의 우선 순위를 갖게 되어 우리의 의도인
(dept_code = 'D5' or dept_code = 'D9') and (salary >= 2700000) 이 아닌,
(dept_code = 'D5') or (dept_code = 'D9' and salary >= 2700000) 이렇게 처리하기 때문에 결과 값이 완전히 달라지게 되는 것이죠.
원하는 결과를 얻기 위해선 중괄호를 이용해 우선순위를 다시 정해줘야 합니다.
select
emp_name 사원명,
dept_code 부서코드,
salary 급여
from
employee
where
(dept_code = 'D5' or dept_code = 'D9')
and
salary >= 2700000;
@실습문제
1. 이름이 '연'으로 끝나는 사원 조회
select
emp_name 사원명
from
employee
where
emp_name like '%연';
2. 전화번호 첫 3자리가 010이 아닌 사원 조회
select
emp_name 사원명,
phone 전화번호
from
employee
where
phone not like '010%';
3. 부서코드가 D5 또는 D9이면서 급여가 270만원 이상인 사원 조회
select
emp_name 사원명,
dept_code 부서코드,
salary 급여
from
employee
where
dept_code in ('D5', 'D9')
and
salary >= 2700000;
4. 직급코드가 J2 또는 J7이고, 입사일이 90/01/01 ~ 01/12/31이고, 급여가 300만원 이상인 사원 조회
select
emp_name 사원명,
job_code 직급코드,
hire_date 입사일,
salary 급여
from
employee
where
job_code in ('J2', 'J7')
and
hire_date between '90/01/01' and '01/12/31'
and
salary >= 3000000;
5. 부서코드가 null인 사원
-- is null 이용
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
dept_code is null;
----------------------------------
-- nvl 이용
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
nvl(dept_code, '인턴') = '인턴';
6. 부서코드가 null이 아닌 사원
-- is not null 이용
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
-- dept_code is null;
dept_code is not null;
----------------------------------
-- nvl 이용
select
emp_name 사원명,
dept_code 부서코드
from
employee
where
nvl(dept_code, '인턴') != '인턴';
'DataBase > Oracle' 카테고리의 다른 글
함수/단일행 처리 함수) 문자 처리 함수(length,lengthb, instr, substr, lapd, rpad, replace, concat, trim, ltrim, rtrim) (0) | 2022.04.14 |
---|---|
DQL) ORDER BY 구문 (오름차순 기준, nulls first/nulls last 옵션) (0) | 2022.04.14 |
DQL) SELECT 구문 (가상 컬럼, nvl()함수, 별칭 alias, 중복 값 제거 distinct, 문자열 연결 연산자 ||, '+' 연산 기호) (0) | 2022.04.14 |
DQL) select 구문 입력 순서, 실제 처리 순서 (0) | 2022.04.12 |
SQL) 기본 SQL 문법 종류 (DDL, DML, DCL, DQL, TCL) 정리 (0) | 2022.04.12 |