콘텐츠로 이동

9. 조건 연산자#

이장에서는 SQL 문에 사용되는 조건 연산자들에 대해서 자세히 설명한다.

SQL 조건의 개요#

SQL 조건은 한 개 이상의 논리 연산자와 수식으로 구성된다. 조건의 반환 값은 TRUE, FALSE, 또는 UNKOWN 셋 중의 하나이다.

조건은 SELECT 구문의 다음 절에 사용될 수 있다:

  • WHERE

  • START WITH

  • CONNECT BY

  • HAVING

또한, 조건은 DELETE 또는 UPDATE 구문의 WHERE 절에도 사용될 수 있다.

이 절은 다양한 종류의 조건에 대해서 상세히 설명한다.

논리 조건#

다음의 논리 조건들이 Altibase에서 지원된다. 다음 표는 각각에 대한 간략한 설명을 보여준다.

논리 연산자 설명
논리곱 (AND) 입력 조건들의 논리곱 결과를 돌려준다. 두 조건이 모두 TRUE이면 TRUE를 반환한다.
둘 중 하나라도 FALSE이면 FALSE를 반환한다.
부정 (NOT) 입력된 값의 반대 결과를 돌려준다.
논리합 (OR) 입력 조건들의 논리합 결과를 돌려준다. 두 조건이 모두 FALSE이면 FALSE를 반환한다.
둘 중 하나라도 TRUE이면 TRUE를 반환한다.

비교 조건#

비교 조건은 단순 비교와 그룹 비교로 분류될 수 있다.

단순 비교 조건은 한 수식이 한 수식과 비교되는 것이다.

그룹 비교 조건은 한 수식이 여러 수식들과 비교되거나 부질의에 의해 반환되는 다수의 행과 비교되는 것이다.

그 외의 조건#

Altibase에서 지원되는 다른 조건들이 다음 표에 간략히 설명되어 있다.

조건 타입 설명
BETWEEN 조건 BETWEEN 조건은 비교 조건의 일종으로 어떤 값이 일정 범위 내에 속하는지 검사한다.
EXISTS 조건 EXISTS 조건은 부질의가 적어도 하나 이상의 행을 반환하는지 검사한다.
IN 조건 IN 조건은 어떤 값이 리스트 또는 부질의가 반환한 결과 중의 하나 이상의 값과 같은지 검사한다.
NOT IN 조건은 어떤 값이 리스트 또는 부질의가 반환한 결과 중의 모든 값과 같지 않은지를 검사한다.
INLIST 조건 INLIST 조건은 어떤 값이 주어진 목록 안에 있는지 검사한다.
IS NULL 조건 IS NULL 조건은 어떤 값이 널인지 검사한다.
LIKE 조건 LIKE 조건은 패턴 일치 검사 조건으로 문자열이 주어진 패턴을 포함하는지 검사한다.
REGEXP_LIKE 조건 REGEXP_LIKE 조건은 문자열이 주어진 정규 표현식을 포함하는지 검사한다.
UNIQUE 조건 UNIQUE 조건은 부질의가 오직 하나의 행을 반환하는지 검사한다.

논리 연산자#

AND#

구문#

condition1 AND condition2

설명#

AND는 condition1condition2를 논리곱 연산한 결과를 돌려준다.

논리곱 연산의 결과는 다음과 같다.

Condition1 (우)

Condition2(하)
TRUE FALSE UNKNOWN
TRUE TRUE FALSE UNKNOWN
FALSE FALSE FALSE FALSE
UNKNOWN UNKNOWN FALSE UNKNOWN

예제#

<질의> 엔지니어이면서 급여가 2000 이상인 직원의 이름, 급여, 입사일을 출력하라.

SELECT e_firstname
     , e_lastname
     , salary
     , join_date
  FROM employees
 WHERE emp_job = 'engineer'
   AND salary >= 2000;
E_FIRSTNAME           E_LASTNAME            SALARY      JOIN_DATE
--------------------------------------------------------------------------
Ken                   Kobain                2000        11-JAN-2010
1 row selected.

NOT#

구문#

NOT condition

설명#

NOT은 입력 condition의 반대 결과를 돌려준다.

Condition TRUE FALSE UNKNOWN
NOT 결과 FALSE TRUE UNKNOWN

예제#

<질의> 1980년 이전에 태어난 사원을 제외한 사원들의 이름, 부서, 생일을 출력하라.

SELECT e_lastname
     , e_firstname
     , dno
     , birth
  FROM employees
 WHERE NOT birth < BYTE'800101';
E_LASTNAME            E_FIRSTNAME           DNO         BIRTH
---------------------------------------------------------------------
Foster                Aaron                 3001        820730
Fleischer             Gottlieb              4002        840417
Wang                  Xiong                 4001        810726
Hammond               Sandra                4002        810211
Jones                 Mitch                 1002        801102
Davenport             Jason                 1003        901212
6 rows selected.

OR#

구문#

condition1 OR condition2

설명#

OR은 condition1condition2를 논리합 연산한 결과를 돌려준다.

논리합 연산의 결과는 다음과 같다.

Condition1 (우)

Condition2(하)
TRUE FALSE UNKNOWN
TRUE TRUE TRUE TRUE
FALSE TRUE FALSE UNKNOWN
UNKNOWN TRUE UNKNOWN UNKNOWN

예제#

<질의> 재고 수량이 20000 이상이거나 단가가 100000원 이상인 상품의 데이터를 출력하라.

SELECT *
  FROM GOODS
 WHERE STOCK > 20000
    OR PRICE >= 100000;
GNO              GNAME            GOODS_LOCATION   STOCK       PRICE       
---------------------------------------------------------------------------------
C111100001       IT-U950          FA0001           35000       7820.55     
D111100008       TM-U200          AC0006           61000       10000       
E111100004       M-190G           CE0001           88000       5638.76     
E111100012       M-U420           CE0003           43200       3566.78     
F111100001       AU-100           AC0010           10000       100000      
5 rows selected.

비교조건#

비교조건은 한 수식이 한 개 또는 여러 개의 수식과 비교되는지에 따라서 크게 단순 비교조건과 그룹 비교조건으로 분류될 수 있다.

단순 비교 조건#

구문#

simple_comparison_condition ::=#

simple_comparison_condition_image260

설명#

단순 비교 조건은 명시된 연산자를 기준으로 양쪽의 수식을 비교하여 TRUE, FALSE 또는 UNKNOWN을 반환한다.

단순 비교 조건은 두 식의 크기를 비교하는 것과 두 식이 동일한지를 판단하는 것으로 분류될 수 있다.

두 개 이상의 수식이 연산자의 양쪽에 존재할 때 (위의 다이어그램에서 아래쪽에 해당), 오직 동등 비교만 수행될 수 있다. 즉, 크기 비교는 불가능하다.

또한, 연산자 왼쪽의 수식 개수는 오른쪽 수식의 개수와 동일해야 한다. 이 규칙은 수식이 부질의(subquery) 형태로 올 경우 SELECT 목록의 개수에도 적용된다.

게다가, 부질의가 단순 비교에 사용될 때 이는 오직 한 레코드만 반환해야 한다.

예제#

<질의> 재고금액이 1억원 이상인 상품의 품명, 보관수량, 원가, 재고금액을 출력하라. (재고금액은 보관수량 * 원가이다.)

SELECT gname
     , stock
     , price
     , stock*price value_of_inv
  FROM goods
 WHERE stock*price > 100000000;
GNAME      STOCK    PRICE      VALUE_OF_INV 
------------------------------------------------
IT-U950    35000    7820.55    273719250 
TM-T88     10000    72000      720000000 
TM-U950    8000     96200      769600000
.
.
.
11 rows selected.

그룹 비교 조건#

구문#

group_comparison_condition ::=#

group_comparison_condition_image267

설명#

그룹 비교 조건에서는 왼쪽의 수식이 오른쪽의 각 수식 또는 부질의 결과와 비교된다. 다수의 행을 반환하는 부질의도 허용된다.

연산자 왼쪽에 두 개 이상의 수식이 올 경우, 오직 동등 비교만 수행될 수 있고, 크기 비교는 불가능하다. 또한, 오른쪽 수식에는 그룹으로 묶기 위해서 괄호를 사용해야 한다. 각 그룹내의 요소들의 개수 또는 부질의에 의해 반환되는 칼럼의 개수는 왼쪽 수식의 개수와 동일해야 한다.

ANY / SOME#

ANY와 SOME 키워드는 같은 의미를 가지고 있다. 이 키워드를 포함하는 그룹 비교 조건은 왼쪽 수식과 오른쪽 수식들 또는 부질의 결과 중 적어도 하나의 수식과 비교한 결과가 TRUE이면, TRUE를 반환한다.

ALL#

ALL 키워드를 포함하는 그룹 비교 조건은 왼쪽의 수식과 오른쪽의 수식들 또는 부질의 결과 모두를 비교해서 모든 경우에 대해서 TRUE일때, TRUE를 반환한다.

예제#

<질의> 성이 "B"로 시작되는 사원이 받은 모든 주문에 대한 정보를 출력하라.

SELECT ono
     , order_date
     , processing
  FROM orders
 WHERE eno = ANY (SELECT eno
                    FROM employees
                   WHERE e_lastname LIKE 'B%');
ONO                  ORDER_DATE   PROCESSING
--------------------------------------------------
12300003             29-DEC-2011  P
12300004             30-DEC-2011  P
12300006             30-DEC-2011  P
12300008             30-DEC-2011  P
12300009             30-DEC-2011  P
12300011             30-DEC-2011  P
12300013             30-DEC-2011  P
12310001             31-DEC-2011  O
12310003             31-DEC-2011  O
12310005             31-DEC-2011  O
12310006             31-DEC-2011  O
12310010             31-DEC-2011  O
12 rows selected.

그 외의 조건#

BETWEEN#

구문#

between_condition ::=#

between_image261

설명#

BEETWEEN 비교는 어떤 값이 주어진 범위에 속하는지를 체크하기 위해 사용된다.

'column1 between x1 and x2'는 'column1 >= x1 and column1 <= x2'와 논리적으로 동일하다.

예제#

<질의> 재고금액이 100만원 이상 1000만원 이하인 상품의 품명, 보관수량, 원가, 재고금액을 출력하라. (재고금액은 보관수량 * 원가이다.)

SELECT gname
     , stock
     , price
     , stock*price value_of_inv
  FROM goods
 WHERE stock*price BETWEEN 1000000 AND 10000000;
GNAME      STOCK      PRICE     VALUE_OF_INV 
------------------------------------------------
IM-310     100        98000     9800000 
.
.
.
M-T500     5000       1000.54   5002700 
7 rows selected.

EXISTS#

구문#

exists_condition ::=#

exists_image265

설명#

EXIST는 부질의의 결과가 적어도 하나 이상 존재하는지 검사한다. 적어도 하나의 행이 존재하면 EXIST는 TRUE를 반환한다.

예제#

<질의> 적어도 두 종류 이상의 상품을 주문한 고객의 고객번호를 출력하라. (먼저 부질의에서는 주문 테이블에서 같은 고객번호이지만 다른 상품을 주문한 행의 쌍을 모두 찾는다. 즉, 한 고객이 한 개 이상의 다른 상품을 주문한 것을 의미한다. 만약, 그러한 행의 쌍이 존재하면, EXISTS는 TRUE를 반환하고, 그 고객번호는 출력된다.)

SELECT DISTINCT cno
  FROM orders a
 WHERE EXISTS (SELECT *
                 FROM orders b
                WHERE a.cno = b.cno
                  AND NOT(a.gno = b.gno));
CNO 
------------------
19
15
14
11
6
5
3
2
1
9 rows selected.

<질의> 모든 상품을 주문한 고객의 이름을 출력하라. 맨 아래쪽에 위치하는 가장 안쪽 질의는 주문 테이블에서 고객이 주문한 상품들을 찾는다. 가운데 질의는 그 고객에 의해 주문되지 않은 상품을 찾는다. 만약, 그 고객에 의해 주문되지 않은 상품이 없으면 그 고객의 이름이 출력될 것이다.)

SELECT customers.c_lastname
  FROM customers
 WHERE NOT EXISTS (SELECT *
                     FROM goods
                    WHERE NOT EXISTS (SELECT *
                                        FROM orders
                                       WHERE orders.cno = customers.cno
                                         AND orders.gno = goods.gno));
CNAME 
------------------------
No rows selected.

IN#

구문#

in_condition ::=#

in_image262

설명#

IN 조건은 '= ANY' 조건을 사용한 그룹 비교와 동일하다. 이런 종류의 조건은 왼쪽의 수식이 오른쪽 수식들 중 어느 하나와 일치하면 TRUE를 반환한다.

NOT IN 조건은 '!= ALL' 조건을 사용한 그룹 비교와 동일하다. 이런 종류의 조건은 오른쪽 수식들 중 어느 하나도 왼쪽 수식과 일치하지 않을 때 TRUE를 반환한다.

예제#

<질의> 응용프로그램 개발 팀 또는 마케팅 팀에서 일하고 있는 사원의 이름, 업무, 전화번호, 입사일을 출력하라.

SELECT e_firstname
     , e_lastname
     , emp_job
     , emp_tel
  FROM employees
 WHERE dno IN (1003, 4001);
E_FIRSTNAME      E_LASTNAME       EMP_JOB          EMP_TEL          
-------------------------------------------------------------------------
Elizabeth        Bae              programmer       0167452000       
Zhen             Liu              webmaster        0114553206 
.
.
.
7 rows selected.

위 SQL문의 WHERE 절은 다음과 같은 의미를 지닌다:

WHERE DNO = 1003 or DNO = 4001

<질의> 상품 C111100001을 주문한 고객의 이름을 출력하라.

SELECT DISTINCT customers.c_lastname
     , customers.c_firstname
  FROM customers
 WHERE customers.cno IN 
       (SELECT orders.cno
          FROM orders
         WHERE orders.gno = 'C111100001');
C_LASTNAME            C_FIRSTNAME
-----------------------------------------------
Martin                Pierre
Fedorov               Fyodor
Dureault              Phil
Sanchez               Estevan
4 rows selected.

INLIST#

구문#

inlist_condition ::=#

inlist_operator

설명#

INLIST는 comma_separated_values 내 각각의 값 중 어느 하나가 expr과 일치하면 TRUE를 반환한다.

NOT INLIST는 comma_separated_values 내 각각의 값 중 어느 것도 expr과 일치하지 않으면 TRUE를 반환한다.

comma_separated_values 내의 각 값은 ASCII 문자로만 이루어진 문자열이어야 한다.

예제#

SELECT dno
     , e_firstname
     , e_lastname
  FROM employees
 WHERE INLIST (dno, '1003, 4001' );
DNO         E_FIRSTNAME           E_LASTNAME
------------------------------------------------------------
1003        Elizabeth             Bae
1003        Zhen                  Liu
1003        Yuu                   Miura
1003        Jason                 Davenport
4001        Xiong                 Wang
4001        Curtis                Diaz
4001        John                  Huxley
7 rows selected.

IS NULL#

구문#

isnull_condition ::=#

isnull_image264

설명#

IS NULL 조건은 표현식(expression)이 널(NULL) 인지 아닌지 검사하기 위해 사용된다.

예제#

<질의> 생일이 입력 되지 않은 직원의 사원번호, 이름, 업무를 출력하라.

SELECT eno
     , e_firstname
     , e_lastname
     , emp_job
  FROM employees
 WHERE salary IS NULL;
ENO         E_FIRSTNAME           E_LASTNAME            EMP_JOB
---------------------------------------------------------------------------
1           Chan-seung            Moon                  CEO
8           Xiong                 Wang                  manager
20          William               Blake                 sales rep
3 rows selected.

LIKE#

구문#

like_condition ::=#

like_image263

설명#

LIKE는 패턴 일치 검사 조건으로써, 어떤 문자열이 주어진 패턴(문자열)을 포함하는지를 검사한다. LIKE 조건은 퍼센트("%")와 밑줄("_") 문자를 와일드카드 문자로 사용한다. "%"는 문자열을 나타내고, "_"는 한 문자를 나타낸다.

그러나 "%" 또는 "_"를 와일드카드 문자가 아닌 실제 문자 "%" 또는 "_"로 사용하려는 경우에는 이스케이프(ESCAPE) 문자를 사용하면 된다. ESCAPE 키워드 다음에 이스케이프 문자로 사용할 문자를 명시하고, 패턴 문자열에서 "%" 또는 "_" 앞에 이 이스케이프 문자를 기술하면, "%" 또는 "_"가 와일드카드 문자로 인식되지 않는다.

패턴 문자열의 길이는 최대 4000 바이트로 제한된다.

예제#

<질의> 성이 "D"로 시작되는 직원들의 사원번호, 이름, 부서번호, 전화번호를 출력하라.

SELECT eno
     , e_lastname
     , e_firstname
     , dno
     , emp_tel
  FROM employees
 WHERE e_lastname LIKE 'D%';
ENO         E_LASTNAME       E_FIRSTNAME      DNO         EMP_TEL          
---------------------------------------------------------------------------------
2           Davenport        Susan                        0113654540       
9           Diaz             Curtis           4001        0165293668       
15          Davenport        Jason            1003        0119556884       
3 rows selected.

<질의> 부서 이름에 밑줄("_")이 포함된 모든 부서에 대한 정보를 출력하라.

INSERT INTO departments VALUES(5002, 'USA_HQ', 'Palo Alto', 100);

SELECT *
  FROM departments
 WHERE dname LIKE '%\_%' ESCAPE '\';
DNO         DNAME            DEP_LOCATION     MGR_NO      
---------------------------------------------------------------
5002        USA_HQ           Palo Alto        100         
1 row selected.

위 예제에서 백슬래시 ("\")가 escape 문자로 정의되었다. 이 escape 문자가 밑줄("_") 앞에 있으므로 밑줄이 와일드카드로 다뤄지지 않는다.

<질의> 이름에 "h"가 들어간 모든 사원의 이름을 출력하라.

SELECT e_firstname
  FROM employees
 WHERE e_firstname LIKE '%h%';
E_FIRSTNAME
------------------------
Chan-seung
Farhad
Elizabeth
Zhen
Mitch
Takahiro
John
7 rows selected.

REGEXP_LIKE#

구문#

regexp_like_condition ::=#

regexp_like_condition

설명#

REGEXP_LIKE는 LIKE 검사 조건과 유사하다. LIKE가 단순한 패턴 일치 검사라면, REGEXP_LIKE는 정규 표현식 일치 검사를 수행한다. Altibase는 POSIX Basic Regular Expression (BRE)을 지원한다. 정규 표현식에 대한 자세한 설명은 "A.부록: 정규 표현식"을 참고하라.

source_expr에는 검색 대상이 되는 칼럼이나 문자 표현식이 올 수 있으며, 일반적으로 CHAR, VARCHAR 같은 문자 타입의 칼럼이 온다.

pattern_expr에는 검색 패턴을 정규 표현식으로 표현한 값이 올 수 있으며, 일반적으로 문자열이 온다. pattern_expr에는 최대 1024 바이트까지 입력할 수 있다.

예제#

<질의> 이름의 성이 "D"로 시작되는 직원들의 사원번호, 이름, 부서번호, 전화번호를 출력하라.

SELECT eno
     , e_lastname
     , e_firstname
     , dno
     , emp_tel
  FROM employees
 WHERE REGEXP_LIKE(e_lastname, '^D');
ENO         E_LASTNAME       E_FIRSTNAME      DNO         EMP_TEL          
---------------------------------------------------------------------------------
2           Davenport        Susan                        0113654540       
9           Diaz             Curtis           4001        0165293668       
15          Davenport        Jason            1003        0119556884       
3 rows selected.

<질의> 이름의 성이 다섯 개의 문자로 이루어진 직원을 출력하라.

SELECT eno
     , e_lastname
     , emp_job
  FROM employees
 WHERE REGEXP_LIKE(TRIM(e_lastname), '^.{5}$');
ENO         E_LASTNAME       EMP_JOB          
--------------------------------------------------
6           Momoi            programmer       
13          Jones            PM               
14          Miura            PM               
20          Blake            sales rep        
4 rows selected.

UNIQUE#

구문#

unique_condition ::=#

unique_image266

설명#

UNIQUE는 부질의가 오직 하나의 레코드만 반환하는지 검사한다.

예제#

<질의> CEO가 오직 한명이면, 다음의 메시지를 출력하라: "There is only one CEO."

SELECT 'There is only one CEO.' message
  FROM DUAL
 WHERE UNIQUE (SELECT *
                 FROM employees
                WHERE emp_job = 'CEO');
MESSAGE
--------------------------
There is only one CEO.
1 row selected.

<질의> 고객 테이블에 여성이 한명만 있을 경우 다음의 메시지를 출력하라: 'There is only one female customer.'

SELECT 'There is only one female customer.' message
  FROM DUAL
 WHERE UNIQUE (SELECT *
                 FROM customers
                WHERE SEX = 'F');
ENAME 
------------------------
No rows selected.