:meta-keywords: cubrid any, cubrid some, cubrid all, cubrid between, cubrid exists, cubrid in, cubrid like, cubrid case clause :meta-description: A comparison expression is an expression that is included in the WHERE clause of the SELECT, UPDATE and DELETE statements, and in the HAVING clause of the SELECT statement. *********** 비교 연산식 *********** .. _basic-cond-expr: 단순 비교 조건식 ================ 비교 조건식은 **SELECT**, **UPDATE**, **DELETE** 문의 **WHERE** 절과 **SELECT** 문의 **HAVING** 절에 포함되는 표현식으로서, 결합되는 연산자의 종류에 따라 단순 비교 조건식, **ANY** / **SOME** / **ALL** 조건식, **BETWEEN** 조건식, **EXISTS** 조건식, **IN** / **NOT IN** 조건식, **LIKE** 조건식, **IS NULL** 조건식이 있다. 먼저, 단순 비교 조건식은 두 개의 비교 가능한 데이터 값을 비교한다. 피연산자로 일반 연산식(expression) 또는 부질의(sub-query)가 지정되며, 피연산자 중 어느 하나가 **NULL** 이면 항상 **NULL** 을 반환한다. 단순 비교 조건식에서 사용할 수 있는 연산자는 아래의 표와 같으며, 보다 자세한 내용은 :doc:`/sql/function/comparison_op` 를 참고한다. **단순 비교 조건식에서 사용할 수 있는 연산자** +-------------+-------------------------------------------------------+---------+----------+ | 비교 연산자 | 설명 | 조건식 | 리턴 값 | +=============+=======================================================+=========+==========+ | **=** | 왼쪽 및 오른쪽 피연산자의 값이 같다. | 1=2 | 0 | +-------------+-------------------------------------------------------+---------+----------+ | **<>** | 왼쪽 및 오른쪽 피연산자의 값이 다르다. | 1<>2 | 1 | | , | | | | | **!=** | | | | +-------------+-------------------------------------------------------+---------+----------+ | **>** | 왼쪽 피연산자는 오른쪽 피연산자보다 값이 크다. | 1>2 | 0 | +-------------+-------------------------------------------------------+---------+----------+ | **<** | 왼쪽 피연산자는 오른쪽 피연산자보다 값이 작다. | 1<2 | 1 | +-------------+-------------------------------------------------------+---------+----------+ | **>=** | 왼쪽 피연산자는 오른쪽 피연산자보다 값이 크거나 같다. | 1>=2 | 0 | +-------------+-------------------------------------------------------+---------+----------+ | **<=** | 왼쪽 피연산자는 오른쪽 피연산자보다 값이 작거나 같다. | 1<=2 | 1 | +-------------+-------------------------------------------------------+---------+----------+ .. _any-some-all-expr: ANY/SOME/ALL 수량어와 그룹 조건식 ================================= **ANY** / **SOME** / **ALL** 과 같은 수량어를 포함하는 그룹 조건식은 하나의 데이터 값과 리스트에 포함된 값들의 일부 또는 모든 값에 대해서 비교 연산을 수행한다. 즉, **ANY** 또는 **SOME** 이 포함된 그룹 조건식은, 왼쪽의 데이터 값이 오른쪽 피연산자로 지정된 리스트 내의 값 중 최소한 하나에 대해 단순 비교 연산자를 만족할 때 **TRUE** 를 반환한다. 한편, **ALL** 이 포함된 그룹 조건식의 경우, 왼쪽 데이터 값이 오른쪽 리스트 내의 모든 값들에 대해 단순 비교 연산자를 만족할 때 **TRUE** 를 반환한다. 만약, **ANY** 또는 **SOME** 을 포함하는 그룹 조건식에서 **NULL** 을 대상으로 비교 연산을 수행하면 그룹 조건식의 결과로 **UNKNOWN** 또는 **TRUE** 를 반환하고, **ALL** 을 포함하는 그룹 조건식에서 **NULL** 을 대상으로 비교 연산을 수행하면 **UNKNOWN** 또는 **FALSE** 를 반환한다. :: expression comp_op SOME expression expression comp_op ANY expression expression comp_op ALL expression * *comp_op* : 비교 연산자 **>**, **<**, **=**, **>=**, **<=** 가 들어갈 수 있다. * *expression* (왼쪽) : 단일 값을 가지는 칼럼, 경로 표현식(예: *tbl_name.col_name*), 상수 값 또는 단일 값을 생성하는 산술 함수가 될 수 있다. * *expression* (오른쪽) : 칼럼 이름, 경로 표현식, 상수 값의 리스트(집합), 부질의가 될 수 있다. 리스트는 중괄호({}) 안에 표현된 집합을 의미하며, 부질의가 사용되면 부질의의 수행 결과 전부에 대해서 *expression* (왼쪽)와 비교 연산을 수행한다. .. code-block:: sql --creating a table CREATE TABLE condition_tbl (id int primary key, name char(10), dept_name VARCHAR, salary INT); INSERT INTO condition_tbl VALUES(1, 'Kim', 'devel', 4000000); INSERT INTO condition_tbl VALUES(2, 'Moy', 'sales', 3000000); INSERT INTO condition_tbl VALUES(3, 'Jones', 'sales', 5400000); INSERT INTO condition_tbl VALUES(4, 'Smith', 'devel', 5500000); INSERT INTO condition_tbl VALUES(5, 'Kim', 'account', 3800000); INSERT INTO condition_tbl VALUES(6, 'Smith', 'devel', 2400000); INSERT INTO condition_tbl VALUES(7, 'Brown', 'account', NULL); --selecting rows where department is sales or devel SELECT * FROM condition_tbl WHERE dept_name = ANY{'devel','sales'}; :: id name dept_name salary ====================================================================== 1 'Kim ' 'devel' 4000000 2 'Moy ' 'sales' 3000000 3 'Jones ' 'sales' 5400000 4 'Smith ' 'devel' 5500000 6 'Smith ' 'devel' 2400000 .. code-block:: sql --selecting rows comparing NULL value in the ALL group conditions SELECT * FROM condition_tbl WHERE salary > ALL{3000000, 4000000, NULL}; :: There are no results. .. code-block:: sql --selecting rows comparing NULL value in the ANY group conditions SELECT * FROM condition_tbl WHERE salary > ANY{3000000, 4000000, NULL}; :: id name dept_name salary ====================================================================== 1 'Kim ' 'devel' 4000000 3 'Jones ' 'sales' 5400000 4 'Smith ' 'devel' 5500000 5 'Kim ' 'account' 3800000 .. code-block:: sql --selecting rows where salary*0.9 is less than those salary in devel department SELECT * FROM condition_tbl WHERE ( (0.9 * salary) < ALL (SELECT salary FROM condition_tbl WHERE dept_name = 'devel') ); :: id name dept_name salary ====================================================================== 6 'Smith ' 'devel' 2400000 .. _between-expr: BETWEEN ======= **BETWEEN** 조건식은 왼쪽의 데이터 값이 오른쪽에 지정된 두 데이터 값 사이에 존재하는지 비교한다. 이때, 왼쪽의 데이터 값이 비교 대상 범위의 경계값과 동일한 경우에도 **TRUE** 를 반환한다. 한편, **BETWEEN** 키워드 앞에 **NOT** 이 오면 **BETWEEN** 연산의 결과에 **NOT** 연산을 수행하여 결과를 반환한다. *i* **BETWEEN** *g* **AND** *m* 은 복합 조건식 *i* **>=** *g* **AND** *i* **<=** *m* 과 동일하다. :: expression [ NOT ] BETWEEN expression AND expression * *expression* : 칼럼 이름, 경로 표현식(예: *tbl_name.col_name*), 상수 값, 산술 표현식, 집계 함수가 될 수 있다. 문자열 표현식인 경우에는 문자의 사전순으로 조건이 평가된다. 표현식 중 하나라도 **NULL** 이 지정되면 **BETWEEN** 조건식의 결과는 **FALSE** 또는 **UNKNOWN** 을 반환한다. .. code-block:: sql --selecting rows where 3000000 <= salary <= 4000000 SELECT * FROM condition_tbl WHERE salary BETWEEN 3000000 AND 4000000; SELECT * FROM condition_tbl WHERE (salary >= 3000000) AND (salary <= 4000000); :: id name dept_name salary ====================================================================== 1 'Kim ' 'devel' 4000000 2 'Moy ' 'sales' 3000000 5 'Kim ' 'account' 3800000 .. code-block:: sql --selecting rows where salary < 3000000 or salary > 4000000 SELECT * FROM condition_tbl WHERE salary NOT BETWEEN 3000000 AND 4000000; :: id name dept_name salary ====================================================================== 3 'Jones ' 'sales' 5400000 4 'Smith ' 'devel' 5500000 6 'Smith ' 'devel' 2400000 .. code-block:: sql --selecting rows where name starts from A to E SELECT * FROM condition_tbl WHERE name BETWEEN 'A' AND 'E'; :: id name dept_name salary ====================================================================== 7 'Brown ' 'account' NULL .. _exists-expr: EXISTS ====== **EXISTS** 조건식은 오른쪽에 지정되는 부질의를 실행한 결과가 하나 이상 존재하면 **TRUE** 를 반환하고, 연산 실행 결과가 공집합이면 **FALSE** 를 반환한다. :: EXISTS expression * *expression* : 부질의가 지정되며, 부질의 실행 결과가 존재하는지 비교한다. 만약 부질의가 어떤 결과도 만들지 않는다면 조건식 결과는 **FALSE** 이다. .. code-block:: sql --selecting rows using EXISTS and subquery SELECT 'raise' FROM db_root WHERE EXISTS( SELECT * FROM condition_tbl WHERE salary < 2500000); :: 'raise' ====================== 'raise' .. code-block:: sql --selecting rows using NOT EXISTS and subquery SELECT 'raise' FROM db_root WHERE NOT EXISTS( SELECT * FROM condition_tbl WHERE salary < 2500000); :: There are no results. .. _in-expr: IN == **IN** 조건식은 왼쪽의 단일 데이터 값이 오른쪽에 지정된 리스트 내에 포함되어 있는지 비교한다. 즉, 왼쪽의 단일 데이터 값이 오른쪽에 지정된 표현식의 원소이면 **TRUE** 를 반환한다. **IN** 키워드 앞에 **NOT** 이 있으면 **IN** 연산의 결과에 **NOT** 연산을 수행하여 결과를 반환한다. :: expression [ NOT ] IN expression * *expression* (left) : 단일 값을 가지는 칼럼, 경로 표현식, 상수 값 또는 단일 값을 생성하는 산술 함수가 될 수 있다. * *expression* (right) : 칼럼 이름, 경로 표현식(예: *tbl_name.col_name*), 상수 값의 리스트(집합), 부질의가 될 수 있다. 리스트는 소괄호(()) 또는 중괄호({}) 안에 표현된 집합을 의미하며, 부질의가 사용되면 부질의의 수행 결과 전부에 대해서 *expression* (left)와 비교 연산을 수행한다. .. code-block:: sql --selecting rows where department is sales or devel SELECT * FROM condition_tbl WHERE dept_name IN {'devel','sales'}; SELECT * FROM condition_tbl WHERE dept_name = ANY{'devel','sales'}; :: id name dept_name salary ====================================================================== 1 'Kim ' 'devel' 4000000 2 'Moy ' 'sales' 3000000 3 'Jones ' 'sales' 5400000 4 'Smith ' 'devel' 5500000 6 'Smith ' 'devel' 2400000 .. code-block:: sql --selecting rows where department is neither sales nor devel SELECT * FROM condition_tbl WHERE dept_name NOT IN {'devel','sales'}; :: id name dept_name salary ====================================================================== 5 'Kim ' 'account' 3800000 7 'Brown ' 'account' NULL .. _is-null-expr: IS NULL ======= **IS NULL** 조건식은 왼쪽에 지정된 표현식의 결과가 **NULL** 인지 비교하여, **NULL** 인 경우 **TRUE** 를 반환하며, 조건절 내에서 사용할 수 있다. **NULL** 키워드 앞에 **NOT** 이 있으면 **IS NULL** 연산의 결과에 **NOT** 연산을 수행하여 결과를 반환한다. :: expression IS [ NOT ] NULL * *expression* : 단일 값을 가지는 칼럼, 경로 표현식(예: *tbl_name.col_name*), 상수 값 또는 단일 값을 생성하는 산술 함수가 될 수 있다. .. code-block:: sql --selecting rows where salary is NULL SELECT * FROM condition_tbl WHERE salary IS NULL; :: id name dept_name salary ====================================================================== 7 'Brown ' 'account' NULL .. code-block:: sql --selecting rows where salary is NOT NULL SELECT * FROM condition_tbl WHERE salary IS NOT NULL; :: id name dept_name salary ====================================================================== 1 'Kim ' 'devel' 4000000 2 'Moy ' 'sales' 3000000 3 'Jones ' 'sales' 5400000 4 'Smith ' 'devel' 5500000 5 'Kim ' 'account' 3800000 6 'Smith ' 'devel' 2400000 .. code-block:: sql --simple comparison operation returns NULL when operand is NULL SELECT * FROM condition_tbl WHERE salary = NULL; :: There are no results. .. _like-expr: LIKE ==== **LIKE** 조건식은 문자열 데이터 간의 패턴을 비교하는 연산을 수행하여, 검색어와 일치하는 패턴의 문자열이 검색되면 **TRUE** 를 반환한다. 패턴 비교 대상이 되는 타입은 **CHAR**, **VARCHAR**, **STRING** 이며, **BIT** 타입에 대해서는 **LIKE** 검색을 수행할 수 없다. **LIKE** 키워드 앞에 **NOT** 이 있으면 **LIKE** 연산의 결과에 **NOT** 연산을 수행하여 결과를 반환한다. **LIKE** 연산자 오른쪽에 오는 검색어에는 임의의 문자 또는 문자열에 대응되는 와일드 카드(wild card) 문자열을 포함할 수 있으며, **%** (percent)와 **_** (underscore)를 사용할 수 있다. **%** 는 길이가 0 이상인 임의의 문자열에 대응되며, **_** 는 1개의 문자에 대응된다. 또한, 이스케이프 문자(escape character)는 와일드 카드 문자 자체에 대한 검색을 수행할 때 사용되는 문자로서, 사용자에 의해 길이가 1인 다른 문자(**NULL**, 알파벳 또는 숫자)로 지정될 수 있다. 와일드 카드 문자 또는 이스케이프 문자를 포함하는 문자열을 검색어로 사용하는 예제는 아래를 참고한다. :: expression [ NOT ] LIKE pattern [ ESCAPE char ] * *expression*\ : 문자열 데이터 타입 칼럼이 지정된다. 패턴 비교는 칼럼 값의 첫 번째 문자부터 시작되며, 대소문자를 구분한다. * *pattern*\ : 검색어를 입력하며, 길이가 0 이상인 문자열이 된다. 이때, 검색어 패턴에는 와일드 카드 문자(**%** 또는 **_**)가 포함될 수 있다. 문자열의 길이는 0 이상이다. * **ESCAPE** *char* : *char* 에 올 수 있는 문자는 **NULL**, 알파벳, 숫자이다. 만약 검색어의 문자열 패턴이 "_" 또는 "%" 자체를 포함하는 경우 이스케이프 문자가 반드시 지정되어야 한다. 예를 들어, 이스케이프 문자를 백슬래시(\\)로 지정한 후 '10%'인 문자열을 검색하고자 한다면, *pattern*\ 에 '10\%'을 지정해야 한다. 또한, 'C:\\'인 문자열을 검색하고자 한다면, *pattern*\ 에 'C:\\ '을 지정하면 된다. CUBRID가 지원하는 문자셋에 관한 상세한 설명은 :ref:`char-data-type` 을 참고한다. LIKE 조건식의 이스케이프 문자 인식은 **cubrid.conf** 파일의 **no_backslash_escapes** 파라미터와 **require_like_escape_character** 파라미터의 설정에 따라 달라진다. 이에 대한 상세한 설명은 :ref:`stmt-type-parameters` 를 참고한다. .. note:: * CUBRID 9.0 미만 버전에서는 UTF-8과 같은 멀티바이트 문자셋 환경에서 입력된 데이터에 대해 문자열 비교 연산을 수행하려면, 1바이트 단위로 문자열 비교를 수행하도록 하는 파라미터(**single_byte_compare** = yes)를 **cubrid.conf** 파일에 추가해야 정상적인 검색 결과를 얻을 수 있다. * CUBRID 9.0 이상 버전에서는 유니코드 문자셋을 지원하므로 **single_byte_compare** 파라미터를 더 이상 사용하지 않는다. .. code-block:: sql --selection rows where name contains lower case 's', not upper case SELECT * FROM condition_tbl WHERE name LIKE '%s%'; :: id name dept_name salary ====================================================================== 3 'Jones ' 'sales' 5400000 .. code-block:: sql --selection rows where second letter is 'O' or 'o' SELECT * FROM condition_tbl WHERE UPPER(name) LIKE '_O%'; :: id name dept_name salary ====================================================================== 2 'Moy ' 'sales' 3000000 3 'Jones ' 'sales' 5400000 .. code-block:: sql --selection rows where name is 3 characters SELECT * FROM condition_tbl WHERE name LIKE '___'; :: id name dept_name salary ====================================================================== 1 'Kim ' 'devel' 4000000 2 'Moy ' 'sales' 3000000 5 'Kim ' 'account' 3800000 .. _case-expr: CASE ==== **CASE** 연산식은 **IF** ... **THEN** ... **ELSE** 로직을 SQL 문장으로 표현하며, **WHEN** 에 지정된 비교 연산 결과가 참이면 **THEN** 절의 값을 반환하고 거짓이면 **ELSE** 절에 명시된 값을 반환한다. 만약, **ELSE** 절이 없다면 **NULL** 값을 반환한다. :: CASE control_expression simple_when_list [ else_clause ] END CASE searched_when_list [ else_clause ] END simple_when : WHEN expression THEN result searched_when : WHEN search_condition THEN result else_clause : ELSE result result : expression | NULL **CASE** 조건식은 반드시 키워드 **END** 로 끝나야 하며, *control_expression* 과 데이터 타입과 *simple_when* 절 내의 *expression* 은 비교 가능한 데이터 타입이어야 한다. 또한, **THEN** 과 **ELSE** 절에 지정된 모든 *result* 의 데이터 타입은 서로 같거나, 어느 하나의 공통 데이터 타입으로 변환 가능(convertible)해야 한다. **CASE** 수식이 반환하는 값의 데이터 타입은 다음과 같은 규칙에 따라 결정된다. * **THEN** 절에 명시된 모든 *result* 의 데이터 타입이 같으면, 해당 타입이 리턴 값의 데이터 타입이 된다. * 모든 *result* 의 데이터 타입이 같지 않더라도 어느 하나의 공통 데이터 타입으로 변환 가능하면, 해당 타입이 리턴 값의 데이터 타입이 된다. * *result* 중 어느 하나가 가변 길이 문자열인 경우, 리턴 값의 데이터 타입은 가변 길이 문자열이 된다. 또한, *result* 가 모두 고정 길이 문자열인 경우에는 가장 긴 길이를 가지는 문자열 또는 비트열이 결과로 반환된다. * *result* 중 어느 하나가 근사치로 표현되는 수치형이면, 근사치로 표현되고 이때 소수점 이하 자릿수는 모든 *result* 의 유효 숫자를 표현할 수 있도록 결정된다. .. code-block:: sql --creating a table CREATE TABLE case_tbl( a INT); INSERT INTO case_tbl VALUES (1); INSERT INTO case_tbl VALUES (2); INSERT INTO case_tbl VALUES (3); INSERT INTO case_tbl VALUES (NULL); --case operation with a search when clause SELECT a, CASE WHEN a=1 THEN 'one' WHEN a=2 THEN 'two' ELSE 'other' END FROM case_tbl; :: a case when a=1 then 'one' when a=2 then 'two' else 'other' end =================================== 1 'one' 2 'two' 3 'other' NULL 'other' .. code-block:: sql --case operation with a simple when clause SELECT a, CASE a WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'other' END FROM case_tbl; :: a case a when 1 then 'one' when 2 then 'two' else 'other' end =================================== 1 'one' 2 'two' 3 'other' NULL 'other' .. code-block:: sql --result types are converted to a single type containing all of significant figures SELECT a, CASE WHEN a=1 THEN 1 WHEN a=2 THEN 1.2345 ELSE 1.234567890 END FROM case_tbl; :: a case when a=1 then 1 when a=2 then 1.2345 else 1.234567890 end =================================== 1 1.000000000 2 1.234500000 3 1.234567890 NULL 1.234567890 .. code-block:: sql --an error occurs when result types are not convertible SELECT a, CASE WHEN a=1 THEN 'one' WHEN a=2 THEN 'two' ELSE 1.2345 END FROM case_tbl; :: ERROR: Cannot coerce 'one' to type double.