Darren's Devlog

[불친절한SQL] 기초쿼리, WHERE절 - 2 본문

SQL

[불친절한SQL] 기초쿼리, WHERE절 - 2

Darren Gwon 2022. 12. 4. 23:16
반응형
LIKE 조건

LIKE 조건은 char1이 char2 패턴과 일치하는 행을 반환한다.

char1과 char2는 문자 값을 사용해야 한다.

LIKE 조건을 패턴 일치 조건으로 부르기도 한다.

char1 [NOT] LIKE char2 [ESCAPE esc_char]

 

char2에 아래의 특수문자를 사용할 수 있다.

특수문자 설명
% 0개 이사의 문자와 일치
_ 하나의 문자와 일치

 

아래 쿼리는  ename이 A로 시작하는 행을 조회한다.

SELECT ename FROM emp WHERE ename LIKE 'A%'

 

아래 쿼리는 ename이 A로 시작하고 S로 끝나는 행을 조회한다.

SELECT ename FROM emp WHERE ename LIKE 'A%S';

아래 쿼리는 ename에 ON이 포함된 행을 조회한다.

SELECT ename FROM emp WHERE ename LIKE '%ON%';

 

아래 쿼리는 ename의 세 번째 문자가 M이고 길이가 5자리인 행을 조회한다.

SELECT ename FROM emp WHERE ename LIKE '__M__';

 

아래 쿼리는 ename에 A가 포함되지 않은 행을 조회한다.

SELECT ename FROM emp WHERE ename NOT LIKE '%A%';

 

특수문자(%, _)를 검색할 경우 ESCAPE 문자를 사용할 수 있다.

아래 쿼리는 \를 ESCAPE 문자로 사용하여 두 번쨰 글자가 %인 패턴을 조회한다.

WITH w1 AS (SELECT 'ABC' AS c1 FROM DUAL UNION ALL
            SELECT 'A%C' AS c1 FROM DUAL)
SELECT c1 FROM w1 WHERE c1 LIKE '_\%_' ESCAPE '\';

 

아래 방식으로도 LIKE 조건을 사용할 수 있다. ename에 AGENT SMITH의 일부가 포함된 행을 조회한다.

아래 쿼리처럼 INSTR 함수를 사용하는 편이 성능 측면에서 유리할 수 있다.

SELECT ename FROM emp WHERE 'AGENT SMITH' LIKE '%' || ename || '%';
SELECT ename FROM emp WHERE INSTR('AGENT SMITH', ename) > 0;

 

NULL 조건

expr이 널인 행을 반환한다.

expr IS [NOT] NULL

 

아래 쿼리는 comm이 NULL 행을 조회한다.

SELECT ename, comm FROM emp WHERE comm IS NULL;

 

아래 쿼리는 comm이 NULL이 아닌 행을 조회한다.

SELECT ename, comm FROM emp WHERE comm IS NOT NULL;

 

아래 쿼리는 comm이 널이거나 0인 행을 조회한다.

SELECT ename, comm FROM emp WHERE (comm IS NULL OR comm = 0);
SELECT ename, comm FROM emp WHERE NVL(comm, 0) = 0;

 

위쪽 쿼리는 불필요한 NVL 함수를 사용했다.

comm이 NULL이면 조건이 0 > 0으로 해석되고, 0 > 0 조건은 항상 FALSE이기 때문이다.

위쪽 퀴리와 아래쪽 쿼리는 결과가 동일하다.

SELECT ename, comm FROM emp WHERE NVL(comm, 0) = 0;
SELECT ename, comm FROM emp WHERE comm > 0;

 

LNNVL 함수

LNNVL 함수는 condition이 FALSE이거나 UNKNOWN이면 TRUE를 반환하고

TRUE이면 FALSE를 반환하는 WHERE 절과 CASE 표현식에 사용할 수 있다.

LNNVL(condition)

 

LNNVL 함수를 사용한 쿼리다. comm이 NULL이거나 0인 행을 조회한다.

위쪽 쿼리는 아래쪽 쿼리와 논리적으로 동일하다.

SELECT ename, comm FROM emp WHERE LNNVL(comm <> 0);
SELECT ename, comm FROM emp WHERE (comm IS NULL OR comm = 0);

 

조건 우선순위

조건은 아래의 우선순위에 따라 평가된다.

우선순위 조건
1 연산자
2 비교 조건(=, <>, >, <, >=, <=)
3 IN 조건, LIKE 조건, BETWEEN 조건, NULL 조건
4 논리 조건 (NOT)
5 논리 조건 (AND)
6 논리 조건 (OR)

 

deptno가 10이나 20이고 job이 CLERK인 행을 조회해보자.

아래의 좌측 쿼리는 의도하지 않은 결과가 반환된다.

AND 조건의 우선순위가 더 높아서 우측 쿼리로 해석이 된다.

SELECT ename, deptno, job
   FROM emp
WHERE deptno = 10
        OR deptno = 20
      AND job = 'CLERK';
SELECT ename, deptno, job
   FROM emp
 WHERE deptno = 10
         OR (         deptno = 20
                 AND job = 'CLERK');

 

아래의 좌측 쿼리도 의도하지 않은 결과가 반환된다.

좌측 쿼리는 조건 우선순위에 따라 우측쿼리로 해석된다.

SELECT ename, deptno, job
   FROM emp
WHERE job = 'CLERK'
      AND deptno = 10
        OR deptno = 20;
SELECT ename, deptno, job
   FROM emp
WHERE (         job = 'CLERK'
                AND deptno = 10)
        OR deptno = 20;

 

아래와 같이 괄호를 사용하면 의도한 결과를 얻을 수 있다.

OR 조건은 반드시 괄호를 사용해야 한다.

우측 쿼리처럼 IN 절을 사용하면 쿼리를 간결하게 작성할 수 있다.

SELECT ename, deptno, job
   FROM emp
WHERE job = 'CLERK'
   AND (       deptno = 10
             OR deptno = 20);
SELECT ename, deptno, job
   FROM emp
WHERE job = 'CLERK'
      AND deptno IN (10, 20);
 

 

아래 쿼리는 우선순위에 의해 결과가 동일하다.

우측 쿼리처럼 작성하는 편이 가동성 측면에서 바람직하다.

부정 조건은 NOT 조건보다 NOT BETWEEN, NOT IN, NOT LIKE, IS NOT NULL 조건을 사용하는 편이 바람직 하다.

SELECT ename, deptno, job
   FROM emp
WHERE job = 'CLERK'
      AND NOT deptno IN (10, 20);
SELECT ename, deptno, job
   FROM emp
WHERE job = 'CLERK'
      AND deptno NOT IN (10, 20);

 

반응형
Comments