:meta-keywords: cubrid seteq, cubrid setneq, cubrid superset, cubrid superseteq, cubrid subset, cubrid subseteq :meta-description: Containment operators are used to check the containment relationship by performing comparison operation on operands of the collection data type. :tocdepth: 3 *********** 포함 연산자 *********** .. contents:: 컬렉션 타입인 피연산자 간 비교 연산을 수행하여 포함(containment) 관계를 확인하기 위해 포함 연산자가 사용된다. 피연산자로 컬렉션 타입 또는 부질의(subquery)를 지정할 수 있으며, 두 피연산자의 포함 관계(동일하다/다르다/부분집합이다/진부분집합이다)에 따라 **TRUE** 또는 **FALSE** 를 반환한다. :: ::= | | (또는 ) | | NULL ::= SETEQ | SETNEQ | SUPERSET | SUBSET | SUPERSETEQ | SUBSETEQ * <*collection_operand*>: 피연산자로 지정될 수 있는 수식은 하나의 집합 값 속성(SET-valued attribute)이거나, 집합 연산자(SET operator)를 지닌 산술 수식(arithmetic expression)이거나, 중괄호로 둘러싸인 집합 값이다. 이때, 중괄호로 둘러싸인 집합 값은 타입을 명시하지 않을 경우 기본적으로 **LIST** 타입으로 처리한다. 피연산자로 부질의가 지정될 수 있으며, 컬렉션 타입이 아닌 칼럼을 조회하는 경우에는 **SET** (*subquery*)과 같이 해당 부질의에 컬렉션 타입 키워드를 붙여야 한다. 부질의에서 조회하는 칼럼은 하나의 집합만 결과로 반환해야 나머지 피연산자 집합과 비교할 수 있다. 컬렉션 원소의 타입이 오브젝트이면, 오브젝트의 내용이 아닌 객체 식별자(OID, object identifier)에 대해 비교한다. 예를 들어, 같은 속성 값을 갖고 OID가 다른 두 오브젝트는 서로 다른 것으로 간주한다. * **NULL**: 비교 대상이 되는 피연산자 중 어느 하나가 **NULL** 인 경우, **NULL** 이 반환된다. 다음은 CUBRID가 지원하는 포함 연산자에 관한 설명 및 리턴 값을 나타낸 표이다. **CUBRID가 지원하는 포함 연산자** +----------------+-------------------------------------+--------------------------+----------+ | 포함 연산자 | 설명 | 조건식 | 리턴 값 | +================+=====================================+==========================+==========+ | A | A = B: | {1,2} SETEQ {1,2,2} | 0 | | **SETEQ** | 집합 A와 집합 B의 원소가 서로 같다. | | | | B | | | | +----------------+-------------------------------------+--------------------------+----------+ | A | A <> B: | {1,2} SETNEQ {1,2,3} | 1 | | **SETNEQ** | 집합 A와 집합 B의 원소가 같지 않다. | | | | B | | | | +----------------+-------------------------------------+--------------------------+----------+ | A | A > B: | {1,2} SUPERSET {1,2,3} | 0 | | **SUPERSET** | 집합 B는 집합 A의 진 부분집합이다. | | | | B | | | | +----------------+-------------------------------------+--------------------------+----------+ | A | A < B: | {1,2} SUBSET {1,2,3} | 1 | | **SUBSET** | 집합 A는 집합 B의 진 부분집합이다. | | | | B | | | | +----------------+-------------------------------------+--------------------------+----------+ | A | A >= B: | {1,2} SUPERSETEQ {1,2,3} | 0 | | **SUPERSETEQ** | 집합 B는 집합 A의 부분 집합이다. | | | | B | | | | +----------------+-------------------------------------+--------------------------+----------+ | A | A <= B: | {1,2} SUBSETEQ {1,2,3} | 1 | | **SUBSETEQ** | 집합 A는 집합 B의 부분 집합이다. | | | | B | | | | +----------------+-------------------------------------+--------------------------+----------+ 다음은 포함 연산자를 이용하는 경우, 피연산자의 타입별 연산 가능 여부 및 타입 변환 여부를 나타낸 표이다. **포함 연산자의 피연산자 타입별 연산 가능 여부** +---------------------+-----------+------------------+-------------------------+ | | SET | MULTISET | LIST(=SEQUENCE) | +=====================+===========+==================+=========================+ | **SET** | 연산 가능 | 연산 가능 | 연산 가능 | +---------------------+-----------+------------------+-------------------------+ | **MULTISET** | 연산 가능 | 연산 가능 | 연산 가능 | | | | | (**LIST** 타입은 | | | | | **MULTISET** | | | | | 타입으로 변환됨) | +---------------------+-----------+------------------+-------------------------+ | **LIST(=SEQUENCE)** | 연산 가능 | 연산 가능 | 일부 연산만 가능 | | | | (**LIST** 타입은 | (**SETEQ**, **SETNEQ**) | | | | **MULTISET** | 나머지 연산은 | | | | 타입으로 변환됨) | 에러 발생 | +---------------------+-----------+------------------+-------------------------+ .. code-block:: sql --empty set is a subset of any set SELECT ({} SUBSETEQ (CAST ({3,1,2} AS SET))); :: Result ============= 1 .. code-block:: sql --operation between set type and null returns null SELECT ((CAST ({3,1,2} AS SET)) SUBSETEQ NULL); :: Result ============= NULL .. code-block:: sql --{1,2,3} seteq {1,2,3} returns true SELECT ((CAST ({3,1,2} AS SET)) SETEQ (CAST ({1,2,3,3} AS SET))); :: Result ============= 1 .. code-block:: sql --{1,2,3} seteq {1,2,3,3} returns false SELECT ((CAST ({3,1,2} AS SET)) SETEQ (CAST ({1,2,3,3} AS MULTISET))); :: Result ============= 0 .. code-block:: sql --{1,2,3} setneq {1,2,3,3} returns true SELECT ((CAST ({3,1,2} AS SET)) SETNEQ (CAST ({1,2,3,3} AS MULTISET))); :: Result ============= 1 .. code-block:: sql --{1,2,3} subseteq {1,2,3,4} returns true SELECT ((CAST ({3,1,2} AS SET)) SUBSETEQ (CAST ({1,2,4,4,3} AS SET))); :: Result ============= 1 .. code-block:: sql --{1,2,3} subseteq {1,2,3,4,4} returns true SELECT ((CAST ({3,1,2} AS SET)) SUBSETEQ (CAST ({1,2,4,4,3} AS MULTISET))); :: Result ============= 1 .. code-block:: sql --{1,2,3} subseteq {1,2,4,4,3} returns true SELECT ((CAST ({3,1,2} AS SET)) SUBSETEQ (CAST ({1,2,4,4,3} AS LIST))); :: Result ============= 0 .. code-block:: sql --{1,2,3} subseteq {1,2,3,4,4} returns true SELECT ((CAST ({3,1,2} AS SET)) SUBSETEQ (CAST ({1,2,3,4,4} AS LIST))); :: Result ============= 1 .. code-block:: sql --{3,1,2} seteq {3,1,2} returns true SELECT ((CAST ({3,1,2} AS LIST)) SETEQ (CAST ({3,1,2} AS LIST))); :: Result ============= 1 .. code-block:: sql --error occurs because LIST subseteq LIST is not supported SELECT ((CAST ({3,1,2} AS LIST)) SUBSETEQ (CAST ({3,1,2} AS LIST))); :: ERROR: ' subseteq ' operator is not defined on types sequence and sequence. SETEQ ===== **SETEQ** 연산자는 첫 번째 피연산자와 두 번째 피연산자가 동일한 경우 **TRUE** (1)을 반환한다. 모든 컬렉션 타입에 대해 비교 연산을 수행할 수 있다. :: collection_operand SETEQ collection_operand .. code-block:: sql --creating a table with SET type address column and LIST type zip_code column CREATE TABLE contain_tbl (id INT PRIMARY KEY, name CHAR(10), address SET VARCHAR(20), zip_code LIST INT); INSERT INTO contain_tbl VALUES(1, 'Kim', {'country', 'state'},{1, 2, 3}); INSERT INTO contain_tbl VALUES(2, 'Moy', {'country', 'state'},{3, 2, 1}); INSERT INTO contain_tbl VALUES(3, 'Jones', {'country', 'state', 'city'},{1,2,3,4}); INSERT INTO contain_tbl VALUES(4, 'Smith', {'country', 'state', 'city', 'street'},{1,2,3,4}); INSERT INTO contain_tbl VALUES(5, 'Kim', {'country', 'state', 'city', 'street'},{1,2,3,4}); INSERT INTO contain_tbl VALUES(6, 'Smith', {'country', 'state', 'city', 'street'},{1,2,3,5}); INSERT INTO contain_tbl VALUES(7, 'Brown', {'country', 'state', 'city', 'street'},{}); --selecting rows when two collection_operands are same in the WEHRE clause SELECT id, name, address, zip_code FROM contain_tbl WHERE address SETEQ {'country','state', 'city'}; :: id name address zip_code =============================================================================== 3 'Jones ' {'city', 'country', 'state'} {1, 2, 3, 4} 1 row selected. .. code-block:: sql --selecting rows when two collection_operands are same in the WEHRE clause SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SETEQ {1,2,3}; :: id name address zip_code =============================================================================== 1 'Kim ' {'country', 'state'} {1, 2, 3} 1 rows selected. SETNEQ ====== **SETNEQ** 연산자는 첫 번째 피연산자와 두 번째 피연산자가 동일하지 않은 경우에 **TRUE** (1)을 반환한다. 모든 컬렉션 타입에 대해 비교 연산을 수행할 수 있다. :: collection_operand SETNEQ collection_operand .. code-block:: sql --selecting rows when two collection_operands are not same in the WEHRE clause SELECT id, name, address, zip_code FROM contain_tbl WHERE address SETNEQ {'country','state', 'city'}; :: id name address zip_code =============================================================================== 1 'Kim ' {'country', 'state'} {1, 2, 3} 2 'Moy ' {'country', 'state'} {3, 2, 1} 4 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 5 'Kim ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 6 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 5} 7 'Brown ' {'city', 'country', 'state', 'street'} {} 6 rows selected. .. code-block:: sql --selecting rows when two collection_operands are not same in the WEHRE clause SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SETNEQ {1,2,3}; :: id name address zip_code =============================================================================== 2 'Moy ' {'country', 'state'} {3, 2, 1} 3 'Jones ' {'city', 'country', 'state'} {1, 2, 3, 4} 4 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 5 'Kim ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 6 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 5} 7 'Brown ' {'city', 'country', 'state', 'street'} {} SUPERSET ======== **SUPERSET** 연산자는 첫 번째 피연산자가 두 번째 피연산자의 모든 원소를 포함하는 경우, 즉 두 번째 피연산자가 첫 번째 피연산자의 진부분집합인 경우 **TRUE** (1)을 반환한다. 피연산자 집합이 서로 동일한 경우에는 **FALSE** (0)을 반환한다. 단, 피연산자가 모두 **LIST** 타입인 경우에는 **SUPERSET** 연산을 지원하지 않는다. :: collection_operand SUPERSET collection_operand .. code-block:: sql --selecting rows when the first operand is a superset of the second operand and they are not same SELECT id, name, address, zip_code FROM contain_tbl WHERE address SUPERSET {'country','state','city'}; :: id name address zip_code =============================================================================== 4 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 5 'Kim ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 6 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 5} 7 'Brown ' {'city', 'country', 'state', 'street'} {} .. code-block:: sql --SUPERSET operator cannot be used for comparison between LIST and LIST type values SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUPERSET {1,2,3}; :: ERROR: ' superset ' operator is not defined on types sequence and sequence. .. code-block:: sql --Comparing operands with a SUPERSET operator after casting LIST type as SET type SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUPERSET (CAST ({1,2,3} AS SET)); :: id name address zip_code =============================================================================== 3 'Jones ' {'city', 'country', 'state'} {1, 2, 3, 4} 4 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 5 'Kim ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 6 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 5} SUPERSETEQ ========== **SUPERSETEQ** 연산자는 첫 번째 피연산자가 두 번째 피연산자의 모든 원소를 포함하거나 서로 동일한 경우, 즉 두 번째 피연산자가 첫 번째 피연산자의 부분집합인 경우 **TRUE** (1)를 반환한다. 단, 피연산자가 모두 **LIST** 타입인 경우에는 **SUPERSETEQ** 연산을 지원하지 않는다. :: collection_operand SUPERSETEQ collection_operand .. code-block:: sql --selecting rows when the first operand is a superset of the second operand SELECT id, name, address, zip_code FROM contain_tbl WHERE address SUPERSETEQ {'country','state','city'}; :: id name address zip_code =============================================================================== 3 'Jones ' {'city', 'country', 'state'} {1, 2, 3, 4} 4 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 5 'Kim ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 6 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 5} 7 'Brown ' {'city', 'country', 'state', 'street'} {} .. code-block:: sql --SUPERSETEQ operator cannot be used for comparison between LIST and LIST type values SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUPERSETEQ {1,2,3}; :: ERROR: ' superseteq ' operator is not defined on types sequence and sequence. .. code-block:: sql --Comparing operands with a SUPERSETEQ operator after casting LIST type as SET type SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUPERSETEQ (CAST ({1,2,3} AS SET)); :: id name address zip_code =============================================================================== 1 'Kim ' {'country', 'state'} {1, 2, 3} 3 'Jones ' {'city', 'country', 'state'} {1, 2, 3, 4} 4 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 5 'Kim ' {'city', 'country', 'state', 'street'} {1, 2, 3, 4} 6 'Smith ' {'city', 'country', 'state', 'street'} {1, 2, 3, 5} SUBSET ====== **SUBSET** 연산자는 두 번째 피연산자가 첫 번째 피연산자의 모든 원소를 포함하는 경우, 즉 첫 번째 피연산자가 두 번째 피연산자의 진부분집합인 경우 **TRUE** (1)을 반환한다. 피연산자 집합이 서로 동일한 경우에는 **FALSE** (0)을 반환한다. 단, 피연산자가 모두 **LIST** 타입인 경우에는 **SUBSET** 연산을 지원하지 않는다. :: collection_operand SUBSET collection_operand .. code-block:: sql --selecting rows when the first operand is a subset of the second operand and they are not same SELECT id, name, address, zip_code FROM contain_tbl WHERE address SUBSET {'country','state','city'}; :: id name address zip_code =============================================================================== 1 'Kim ' {'country', 'state'} {1, 2, 3} 2 'Moy ' {'country', 'state'} {3, 2, 1} --SUBSET operator cannot be used for comparison between LIST and LIST type values SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUBSET {1,2,3}; :: ERROR: ' subset ' operator is not defined on types sequence and sequence. --Comparing operands with a SUBSET operator after casting LIST type as SET type SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUBSET (CAST ({1,2,3} AS SET)); :: id name address zip_code =============================================================================== 7 'Brown ' {'city', 'country', 'state', 'street'} {} SUBSETEQ ======== **SUBSETEQ** 연산자는 두 번째 피연산자가 첫 번째 피연산자의 모든 원소를 포함하거나 서로 동일한 경우, 즉 첫 번째 피연산자가 두 번째 피연산자의 부분집합인 경우 **TRUE** (1)을 반환한다. 단, 피연산자가 모두 **LIST** 타입인 경우에는 **SUBSETEQ** 연산을 지원하지 않는다. :: collection_operand SUBSETEQ collection_operand .. code-block:: sql --selecting rows when the first operand is a subset of the second operand SELECT id, name, address, zip_code FROM contain_tbl WHERE address SUBSETEQ {'country','state','city'}; :: id name address zip_code =============================================================================== 1 'Kim ' {'country', 'state'} {1, 2, 3} 2 'Moy ' {'country', 'state'} {3, 2, 1} 3 'Jones ' {'city', 'country', 'state'} {1, 2, 3, 4} .. code-block:: sql --SUBSETEQ operator cannot be used for comparison between LIST and LIST type values SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUBSETEQ {1,2,3}; :: ERROR: ' subseteq ' operator is not defined on types sequence and sequence. .. code-block:: sql --Comparing operands with a SUBSETEQ operator after casting LIST type as SET type SELECT id, name, address, zip_code FROM contain_tbl WHERE zip_code SUBSETEQ (CAST ({1,2,3} AS SET)); :: id name address zip_code =============================================================================== 1 'Kim ' {'country', 'state'} {1, 2, 3} 7 'Brown ' {'city', 'country', 'state', 'street'} {}