데이터 정렬 지원

데이터 정렬을 사용하면 특정 언어 또는 기타 사용자 지정 규칙에 따라 데이터를 비교하고 정렬하는 데 사용할 수 있는 문자열을 비교하기 위한 대체 규칙을 지정할 수 있습니다.

개요

다음 섹션에서는 데이터 정렬이 무엇인지, 그리고 문자열을 비교할 때 데이터 정렬을 사용하는 방법을 설명합니다.

데이터 정렬 이해하기

Snowflake의 텍스트 문자열은 UTF-8 문자 세트를 사용하여 저장되며, 기본적으로 문자열에 있는 문자를 나타내는 유니코드 코드에 따라 문자열이 비교됩니다.

하지만 UTF-8 문자 표현을 기반으로 문자열을 비교하면 원하는/예상한 동작이 수행되지 않을 수 있습니다. 예:

  • 특정 언어의 특수 문자가 해당 언어의 순서 기준에 따라 정렬되지 않으면 정렬 시 예기치 않은 결과가 반환될 수 있습니다.

  • 문자가 대문자인지 소문자인지 여부를 무시하는 것과 같이, 다른 규칙에 따라 문자열을 정렬할 수도 있습니다.

데이터 정렬을 사용하면 다음을 기준으로 문자열 비교에 사용할 규칙을 명시적으로 지정할 수 있습니다.

  • 다양한 로캘(즉, 다양한 언어의 다양한 문자 세트).

  • 대/소문자 구분(즉, 문자열을 변환하기 위해 UPPER 또는 LOWER 함수를 명시적으로 호출하지 않고 대/소문자를 구분하거나 대/소문자 구분하지 않는 문자열 비교를 사용할지 여부).

  • 악센트 구분(예: Z, Ź, Ż 가 똑같은 문자나 다른 문자로 간주되는지 여부).

  • 구두점 구분(즉, 비교에서 문자만 사용할지, 모든 문자를 포함할지 여부). 예를 들어, 비교에서 구두점을 구분하지 않는 경우 A-B-CABC 는 똑같은 것으로 취급됩니다.

  • 문자열의 첫 글자를 기준으로 정렬하기 위한 기본 설정과 선행 및/또는 후행 공백 제거와 같은 추가 옵션.

데이터 정렬을 위한 용도

데이터 정렬은 다음을 포함한(단, 이에 국한되지 않음) 다양한 작업에서 사용할 수 있습니다.

사용법

링크

단순 비교

... WHERE column1 = column2 ...

WHERE

조인

... ON table1.column1 = table2.column2 ...

JOIN

정렬

... ORDER BY column1 ...

ORDER BY

Top-K 정렬

... ORDER BY column1 LIMIT N ...

LIMIT / FETCH

집계

... GROUP BY ...

GROUP BY

Window 절

... PARTITION BY ... ORDER BY ...

윈도우 함수

스칼라 함수

... LEAST(column1, column2, column3) ...

스칼라 함수

집계 함수

... MIN(column1), MAX(column1) ...

집계 함수

데이터 클러스터링

... CLUSTER BY (column1) ...

클러스터링 키 및 클러스터링된 테이블

데이터 정렬 제어

데이터 정렬 제어는 세분화됩니다. 다음에 사용할 데이터 정렬을 명시적으로 지정할 수 있습니다.

  • 계정 수준 매개 변수 DEFAULT_DDL_COLLATION 을 사용하는 계정.

  • ALTER DATABASE 명령을 사용하여 데이터베이스에 추가된 모든 테이블의 모든 열.

  • ALTER SCHEMA 명령을 사용하여 스키마에 추가된 모든 테이블의 모든 열.

  • ALTER TABLE 명령을 사용하여 테이블에 추가된 모든 열.

  • CREATE TABLE 명령을 사용하는 테이블의 개별 열.

  • SQL 문 내의 특정 비교(예: WHERE col1 = col2). 여러 데이터 정렬이 문에 적용되는 경우, Snowflake는 우선 순위를 기준으로 사용할 데이터 정렬을 결정합니다. 우선 순위에 대한 자세한 내용은 이 항목에 있는 다중 문자열 작업에서 데이터 정렬 우선 순위 섹션을 참조하십시오.

데이터 정렬 SQL 구문

데이터 정렬을 위해 다음 SQL 구문을 사용할 수 있습니다.

COLLATE 절(테이블 열 정의용)

테이블 열의 정의에 선택적 COLLATE 절을 추가하면 열의 데이터에 대해 수행되는 비교 및 기타 관련 작업에 지정된 데이터 정렬이 사용됨을 나타냅니다.

CREATE TABLE <table_name> ( <col_name> <col_type> COLLATE '<collation_specification>'
                            [ , <col_name> <col_type> COLLATE '<collation_specification>' ... ]
                            [ , ... ]
                          )
Copy

열에 대해 지정된 COLLATE 절이 없는 경우, Snowflake는 UTF-8 문자 표현을 기준으로 문자열을 비교하는 기본값을 사용합니다.

또한, Snowflake는 데이터 정렬 사양(예: COLLATE '')에 대해 빈 문자열 지정을 지원하는데, 이는 열에 대해 아무런 데이터 정렬도 지정하지 않는 것과 같습니다.

하지만 우선 순위로 인해 열에 대해 COLLATE '' 를 지정하더라도 COLLATE 'utf8' 을 명시적으로 지정하는 것과 같은 효과는 없습니다. 자세한 내용은 이 항목의 다중 문자열 작업에서 데이터 정렬 우선 순위 섹션을 참조하십시오.

테이블의 열에 대해 데이터 정렬을 지정했는지 여부를 확인하려면 DESCRIBE TABLE 을 사용하십시오(또는 특정 열에 대한 데이터 정렬이 있는 경우 COLLATION 함수를 사용하여 데이터 정렬을 봄).

COLLATE 함수

이 함수는 입력 문자열 식에서 지정된 데이터 정렬을 사용합니다.

COLLATE( <expression> , '[<collation_specification>]' )
Copy

이 함수는 중위 표기법을 사용하여 호출할 수도 있습니다.

<expression> COLLATE '[<collation_specification>]'
Copy

이 함수는 특정 작업(예: 정렬)에 대한 특정 데이터 정렬을 명시적으로 지정하는 데 특히 유용하지만, 다음 목적으로도 사용할 수 있습니다.

  • 하위 쿼리의 SELECT 절에서 데이터 정렬을 허용하여 외부 쿼리의 지정된 열에 대한 모든 작업이 데이터 정렬을 사용하도록 합니다.

  • 지정된 데이터 정렬과 함께 CTAS를 사용하여 테이블을 만듭니다.

예:

-- Evaluates using "English case-insensitive" collation:
SELECT * FROM t1 WHERE COLLATE(col1 , 'en-ci') = 'Tango';

-- Sorts the results using German (Deutsch) collation.
SELECT * FROM t1 ORDER BY COLLATE(col1 , 'de');

-- Creates a table with a column using French collation.
CREATE TABLE t2 AS SELECT COLLATE(col1, 'fr') AS col1 FROM t1;

-- Creates a table with a column using French collation.
CREATE TABLE t2 AS SELECT col1 COLLATE 'fr' AS col1 FROM t1;
Copy

COLLATION 함수

이 함수는 테이블 열을 포함하여, 식에 사용된 데이터 정렬 사양을 반환합니다.

COLLATION( <expression> )
Copy

식에 대해 지정된 데이터 정렬이 없는 경우 이 함수는 NULL 을 반환합니다.

일반적으로, 열 이름에 이를 사용하는 경우 테이블의 각 행에 대한 출력의 한 행을 가져오지 못하도록 DISTINCT 를 사용해야 합니다. 예:

SELECT DISTINCT COLLATION(column1) FROM table1;
Copy

참고

이 함수는 우선 순위 수준이 아닌, 데이터 정렬 사양만 반환합니다. 우선 순위에 대한 자세한 내용은 이 항목에 있는 다중 문자열 작업에서 데이터 정렬 우선 순위 섹션을 참조하십시오.

데이터 정렬 사양

COLLATE 절(테이블 열의 경우) 또는 COLLATE 함수(식의 경우)를 사용할 때는 열/식에 사용되는 비교 논리를 결정하는 데이터 정렬 사양을 포함해야 합니다.

데이터 정렬 사양은 다음과 같은 형식으로 하이픈(-)으로 구분된 하나 이상의 지정자로 구성된 문자열로 이루어집니다.

'<specifier>[-<specifier> ...]'

다음 지정자가 지원됩니다(자세한 내용은 이 항목의 지원되는 지정자 참조).

  • 로캘.

  • 대/소문자 구분.

  • 악센트 구분.

  • 문장 부호 구분.

  • 첫 글자 기본 설정.

  • 대/소문자 변환.

  • 공백 제거.

지정자는 대/소문자를 구분하지 않으며, 사용할 경우 항상 먼저 와야 하는 로캘을 제외하고 임의의 순서가 될 수 있습니다.

다음 섹션에서는 데이터 정렬 사양에 대해 더 자세히 설명합니다.

사양 예

데이터 정렬 사양 문자열의 몇 가지 예는 다음과 같습니다.

  • 'de': 독일어 로캘.

  • 'de-ci-pi': 대/소문자와 문장 부호를 구분하지 않는 비교를 포함한 독일어 로캘.

  • 'fr_CA-ai': 악센트를 구분하지 않는 비교를 포함한 캐나다 프랑스어 로캘.

  • 'en_US-trim': 비교 전에 선행 공백과 후행 공백이 잘리는 US 영어 로캘.

아무런 데이터 정렬도 사용하지 않음을 나타내는 데이터 정렬 사양(예: COLLATE '' 또는 COLLATE(col1, ''))에 대해 빈 문자열을 지정할 수도 있습니다.

지원되는 지정자

로캘:

적용할 언어별 규칙과 국가별 규칙을 지정합니다.

language_country 형식의 언어 코드(필수)와 국가 코드(선택)로 구성된 유효한 로캘 문자열을 지원합니다. 몇 가지 로캘 예는 다음과 같습니다.

  • en - 영어.

  • en_US - 미국 영어.

  • fr - 프랑스어.

  • fr_CA - 캐나다 프랑스어.

또한, utf8 의사 로캘은 기본값인 유니코드 순서를 사용하도록 지정합니다. 자세한 내용은 이 항목의 UTF-8과 로캘 데이터 정렬을 사용한 정렬 섹션을 참조하십시오.

로캘 지정자는 선택 사항이지만, 사용할 경우 문자열의 첫 번째 지정자여야 합니다.

대/소문자 구분:

값을 비교할 때 대/소문자를 고려해야 할지 여부를 결정합니다. 가능한 값은 다음과 같습니다.

  • cs - 대/소문자 구분(기본값).

  • ci - 대/소문자 구분 안 함.

예:

데이터 정렬 사양

결과

'en-ci'

Abc = abc

True

'en-cs' / en

Abc = abc

False

악센트 구분:

악센트가 있는 문자를 기본 문자와 같거나 다른 것으로 간주해야 할지 여부를 결정합니다. 가능한 값은 다음과 같습니다.

  • as - 악센트 구분(기본값).

  • ai - - 악센트 구분 안 함.

예:

데이터 정렬 사양

결과

참고

'fr-ai'

E = É

True

'fr-as' / 'fr'

E = É

False

'en-ai'

a = ą

True

영어에서 이러한 문자는 악센트 차이만 있는 것으로 처리되므로, 악센트 구분 안 함을 지정하면 값 비교 결과가 같은 것으로 나옵니다.

'pl-ai'

a = ą

False

폴란드어에서 이러한 문자는 별개의 기본 문자로 처리되므로, 악센트 구분 안 함이 지정되었는지 여부와 관계없이 비교 결과가 항상 같지 않은 것으로 나옵니다.

'pl-as' / 'pl'

a = ą

False

악센트 구분 및 데이터 정렬에 대한 규칙은 언어마다 다릅니다. 예를 들어, 일부 언어에서는 데이터 정렬이 항상 악센트를 구분하며 악센트를 구분하지 않는 데이터 정렬을 지정해도 이를 해제할 수 없습니다.

문장 부호 구분:

글자가 아닌 문자가 중요한지 여부를 결정합니다. 가능한 값은 다음과 같습니다.

  • ps - 문장 부호 구분.

  • pi - 문장 부호 구분 안 함.

기본값은 로캘에 따라 다릅니다(즉, 문장 부호 구분이 지정되어 있지 않으면 로캘별 규칙이 사용됨). 대부분의 경우, 규칙은 ps 와 동일합니다.

예:

데이터 정렬 사양

결과

참고

'en-pi'

A-B-C = ABC

True

'en-ps'

A-B-C = ABC

False

첫 글자 기본 설정:

정렬할 때 대문자 또는 소문자를 먼저 표시할지 여부를 결정합니다. 가능한 값은 다음과 같습니다.

  • fl - 소문자가 먼저 정렬됩니다.

  • fu - 대문자가 먼저 정렬됩니다.

기본값은 로캘마다 다릅니다(즉, 값이 지정되지 않은 경우 로캘별 순서가 사용됨). 대부분의 경우, 순서는 fl 과 동일합니다.

또한, 이 지정자는 같음 비교에 영향을 주지 않습니다.

대/소문자 변환:

비교 전에 문자열이 소문자 또는 대문자로 변환됩니다. 어떤 상황에서는 이것이 전체 로캘별 데이터 정렬보다 빠릅니다. 가능한 값은 다음과 같습니다.

  • upper - 비교 전에 문자열을 대문자로 변환합니다.

  • lower - 비교 전에 문자열을 소문자로 변환합니다.

이 지정자에는 기본값이 없습니다(즉, 지정된 값이 없으면 어떤 변환도 발생하지 않음).

공백 제거:

비교 전에 문자열에서 선행/후행 공백을 제거합니다. 이 기능은 SQL CHAR 데이터 타입에 대해 의미 체계에서 동일한 비교(매우 드문 코너 케이스 제외)를 수행하는 데 유용할 수 있습니다.

가능한 값은 다음과 같습니다.

  • trim - 비교 전에 선행 공백과 후행 공백을 모두 제거합니다.

  • ltrim - 비교 전에 선행 공백만 제거합니다.

  • rtrim - 비교 전에 후행 공백만 제거합니다.

이 지정자에는 기본값이 없습니다(즉, 지정된 값이 없으면 제거가 수행되지 않음).

예:

데이터 정렬 사양

결과

참고

'en-trim'

__ABC_ = ABC

True

이런 예의 목적상, 밑줄 문자는 공백을 나타냅니다.

'en-ltrim'

__ABC_ = ABC

False

'en-rtrim'

__ABC_ = ABC

False

'en'

__ABC_ = ABC

False

데이터 정렬 구현 세부 정보

다음 섹션에서 데이터 정렬 지원에 대해 더 자세히 설명합니다.

대/소문자 구분 없는 비교

대문자 문자열 비교와 원래 문자열 비교

일부 언어에는 두 소문자에 상응하는 대문자가 똑같은 경우가 있습니다. 예를 들어, 일부 언어에서는 소문자 I (iı)의 점선 형식과 비점선 형식을 모두 지원합니다. 문자열을 대문자로 강제 적용하면 비교에 영향을 줍니다.

다음은 그 차이점을 보여줍니다.

테이블 만들기:

create or replace table test_table (col1 varchar, col2 varchar);
insert into test_table values ('ı', 'i');
Copy

데이터를 쿼리합니다.

select col1 = col2,
       COLLATE(col1, 'lower') = COLLATE(col2, 'lower'),
       COLLATE(col1, 'upper') = COLLATE(col2, 'upper')
    from test_table;
+-------------+-------------------------------------------------+-------------------------------------------------+
| COL1 = COL2 | COLLATE(COL1, 'LOWER') = COLLATE(COL2, 'LOWER') | COLLATE(COL1, 'UPPER') = COLLATE(COL2, 'UPPER') |
|-------------+-------------------------------------------------+-------------------------------------------------|
| False       | False                                           | True                                            |
+-------------+-------------------------------------------------+-------------------------------------------------+
Copy

문자 가중치

Snowflake는 다음 데이터 정렬 사양 을 지원합니다.

  • ICU (International Components for Unicode).

  • Snowflake 관련 데이터 정렬 사양(예: upperlower).

ICU로 정의되고 대/소문자를 구분하지 않는 비교 작업의 경우 Snowflake는 UCA(Unicode Collation Algorithm) 를 따르고 유니코드 문자의 3차 가중치가 아닌 1차 및 2차 가중치만 고려합니다. 3차 가중치만 다른 문자는 동일한 것으로 처리됩니다. 예를 들어, en-ci 데이터 정렬 사양을 사용하면 공백과 줄 바꿈하지 않는 공백이 동일한 것으로 간주됩니다.

UTF-8과 로캘 데이터 정렬을 사용한 정렬

문자열은 항상 UTF-8로 Snowflake 내부에 저장되고 UTF-8에서 지원하는 모든 언어의 모든 문자를 나타낼 수 있으므로, 기본 데이터 정렬은 UTF-8(즉, 'utf8' )입니다.

UTF-8 데이터 정렬은 문자의 알파벳 순서와 반대로 문자의 숫자 표현을 기반으로 합니다.

이는 각 ASCII 문자의 서수 값을 기준으로 정렬하는 것과 유사한데, 대문자는 소문자보다 낮은 서수 값을 가지므로 각별히 주의해야 합니다.

A = 65
B = 66
...
a = 97
b = 98
...

결과적으로 다음과 같습니다.

  • UTF-8 순서로 정렬하면 모든 대문자가 모든 소문자에 앞서 반환됩니다.

    A , B , … , Y , Z , … , a , b , … , y , z

  • 반대로, 'en' 데이터 정렬 사양은 (UTF-8 내부 표현을 사용하는 대신) 알파벳순으로 정렬하여 Aa 가 모두 Bb 에 앞서 반환됩니다.

    a , A , b , B , …

또한, csci 대/소문자 구분 지정자의 차이점도 정렬에 영향을 줍니다.

  • cs (대/소문자 구분)는 항상 똑같은 문자의 대문자 버전에 앞서 소문자 버전부터 반환합니다. 예를 들어 'en-cs' 를 사용하는 경우 다음과 같습니다.

    a , A , b , B , …

    대/소문자 구분이 기본값이므로, 'en-cs''en' 은 똑같습니다.

  • ci (대/소문자 구분 안 함)는 대문자 및 소문자 버전의 문자를 서로에 대해 임의로 반환하지만, 여전히 이후 버전의 대문자 및 소문자보다 모두 먼저 반환합니다. 예를 들어 'en-ci' 를 사용하는 경우는 다음과 같습니다.

    A , a , b , B , …

영문자 이외의 일부 문자는 데이터 정렬 설정에 따라 다르게 정렬될 수도 있습니다. 다음 코드 예에서는 더하기 문자(+ )와 빼기 문자(- )가 서로 다른 데이터 정렬 설정에 대해 다르게 정렬됨을 보여줍니다.

테이블 만들기:

create or replace table demo (
    no_explicit_collation VARCHAR,
    en_ci VARCHAR COLLATE 'en-ci',
    en VARCHAR COLLATE 'en',
    utf_8 VARCHAR collate 'utf8');
insert into demo (no_explicit_collation) values
    ('-'),
    ('+');
update demo SET
    en_ci = no_explicit_collation,
    en = no_explicit_collation,
    utf_8 = no_explicit_collation;
Copy

데이터를 쿼리합니다.

select max(no_explicit_collation), max(en_ci), max(en), max(utf_8)
    from demo;
+----------------------------+------------+---------+------------+
| MAX(NO_EXPLICIT_COLLATION) | MAX(EN_CI) | MAX(EN) | MAX(UTF_8) |
|----------------------------+------------+---------+------------|
| -                          | +          | +       | -          |
+----------------------------+------------+---------+------------+
Copy

다중 문자열 작업에서 데이터 정렬 우선 순위

두 개 이상의 문자열에 대한 작업을 수행할 때 서로 다른 문자열에 대해 서로 다른 데이터 정렬이 지정될 수 있습니다. 적용할 데이터 정렬의 결정은 각 입력에 대한 데이터 정렬 지정 방식과 각 지정자의 우선 순위에 따라 다릅니다.

다음 3가지 우선 순위 수준(최고부터 최저까지)이 있습니다.

함수:

SQL 문에서 COLLATE 함수 함수를 사용하여 데이터 정렬이 지정됩니다.

:

열 정의에 데이터 정렬이 지정되었습니다.

없음:

주어진 식/열에 대해 데이터 정렬이 지정되지 않거나 지정되지 않았거나, 사양이 비어 있는 데이터 정렬이 사용되거나 사용되었습니다(예: COLLATE(col1, '') 또는 col1 STRING COLLATE '').

사용할 데이터 정렬을 결정할 때 우선 순위가 가장 높은 데이터 정렬 사양이 사용됩니다. 여러 데이터 정렬이 지정되고 그들의 우선 순위 수준이 같으면 값을 비교하고, 같지 않으면 오류가 반환됩니다.

예를 들어 다음과 같은 열 수준 데이터 정렬 사양이 있는 테이블을 생각해보십시오.

CREATE OR REPLACE TABLE collation_precedence_example(
  col1    VARCHAR,               -- equivalent to COLLATE ''
  col2_fr VARCHAR COLLATE 'fr',  -- French locale
  col3_de VARCHAR COLLATE 'de'   -- German locale
);
Copy

두 문자열을 비교하는 문에 테이블을 사용하는 경우 데이터 정렬은 다음과 같이 적용됩니다.

-- Uses the 'fr' collation because the precedence for col2_fr is higher than
-- the precendence for col1.
... WHERE col1 = col2_fr ...

-- Uses the 'en' collation, because it is explicitly specified in the statement,
-- which takes precedence over the collation for col2_fr.
... WHERE col1 COLLATE 'en' = col2_fr ...

-- Returns an error because the expressions have different collations at the same
-- precedence level.
... WHERE col2_fr = col3_de ...

-- Uses the 'de' collation because collation for col2_fr has been removed.
... WHERE col2_fr COLLATE '' = col3_de ...

-- Returns an error because the expressions have different collations at the same
-- precedence level.
... WHERE col2_fr COLLATE 'en' = col3_de COLLATE 'de' ...
Copy

참고

Snowflake의 기본 데이터 정렬은 'utf8' 이지만, 명시적 데이터 정렬의 우선 순위가 데이터 정렬이 없는 것보다 높으므로 빈 문자열을 지정하거나 데이터 정렬을 지정하지 않는 것은 'utf8' 을 명시적으로 지정하는 것과 다릅니다. 아래 코드 예의 마지막 두 문이 그 차이점을 보여줍니다.

CREATE OR REPLACE TABLE collation_precedence_example2(
  s1 STRING COLLATE '',
  s2 STRING COLLATE 'utf8',
  s3 STRING COLLATE 'fr'
);

-- Uses 'utf8' because s1 has no collation and 'utf8' is the default.
SELECT * FROM collation_precedence_example2 WHERE s1 = 'a';

-- Uses 'utf8' because s1 has no collation and s2 has explicit 'utf8' collation.
SELECT * FROM collation_precedence_example2 WHERE s1 = s2;
Copy

이 예는 s1에 데이터 정렬이 없고 s3에는 명시적 fr 데이터 정렬이 있어 오류 없이 실행되므로 명시적 데이터 정렬이 우선합니다.

SELECT * FROM collation_precedence_example2 WHERE s1 = s3;
+----+----+----+
| S1 | S2 | S3 |
|----+----+----|
+----+----+----+
Copy

이 예에서는 s2와 s3이 같은 우선 순위 수준에서 서로 다른 데이터 정렬이 지정되어 있으므로 오류가 발생합니다.

SELECT * FROM collation_precedence_example2 WHERE s2 = s3;
Copy

출력:

002322 (42846): SQL compilation error: Incompatible collations: 'fr' and 'utf8'
Copy

내장 함수에서 데이터 정렬에 대해 제한적인 지원

데이터 정렬은 문자열 함수 중 일부에서만 지원됩니다. 데이터 정렬을 구현할 것으로 합리적으로 예상할 수 있지만 아직 데이터 정렬을 지원하지 않는 함수는 데이터 정렬과 함께 사용할 때 오류를 반환합니다. 이러한 오류 메시지는 COLLATE 함수를 호출할 때뿐만 아니라, 해당 열을 생성한 CREATE TABLE 또는 ALTER TABLE 문에서 데이터가 정렬된 것으로 정의된 열에 대해 문자열 함수를 호출할 때도 표시됩니다.

현재, 데이터 정렬은 단순 비교 작업에만 영향을 줍니다.

예를 들어, POSITION('abc' in COLLATE('ABC', 'en-ci')) 는 대/소문자를 구분하지 않는 데이터 정렬이 지정되더라도 ABC 에서 abc 를 찾지 않습니다.

데이터 정렬을 지원하는 함수

다음 함수는 데이터 정렬을 지원합니다.

이들 함수 중 일부는 데이터 정렬과 함께 사용하는 데 제한이 있습니다. 자세한 내용은 각 특정 함수의 설명서를 참조하십시오.

이 목록은 시간이 지나며 늘어날 수 있습니다.

조심

|| (연결) 및 LIKE 와 같은 일부 SQL 연산자와 조건자는 함수로 구현되고 함수로 사용할 수 있습니다(예: LIKE()CONCAT()). 조건자 또는 연산자가 함수로 구현되고 함수가 데이터 정렬을 지원하지 않는 경우에는 조건자나 연산자가 데이터 정렬을 지원하지 않습니다.

데이터 정렬 제한 사항 도 참조하십시오.

데이터 정렬 사용의 성능 영향

데이터 정렬을 사용하면 다양한 데이터베이스 작업의 성능에 영향을 줄 수 있습니다.

  • 비교와 관련된 작업은 더 느릴 수 있습니다.

    이는 간단한 WHERE 절뿐 아니라 조인, 정렬, GROUP BY 작업 등에도 영향을 줄 수 있습니다.

  • WHERE 조건자에서 일부 함수와 함께 사용 시, 마이크로 파티션 잘라내기의 효율성이 떨어질 수 있습니다.

  • 열에 대해 지정된 데이터 정렬과 다른 WHERE 조건자에서 데이터 정렬을 사용하면 잘라내기 효율성이 감소하거나 잘라내기가 완전히 제거되는 결과를 낳을 수 있습니다.

데이터 정렬 사용을 위한 추가적인 고려 사항

  • 이름의 유사성에도 불구하고, 다음 데이터 정렬 함수는 다른 결과를 반환한다는 점을 기억하십시오.

    • COLLATE 는 어떤 데이터 정렬을 사용할지 명시적으로 지정합니다.

    • COLLATION 은 아무것도 명시적으로 지정하지 않은 경우 어떤 데이터 정렬이 사용되는지 보여줍니다.

  • 데이터 정렬 사양이 있는 열에서는 정렬에 영향을 줄 수 있는 데이터 정렬의 로캘에 없는 문자를 사용할 수 있습니다.

    예를 들어, 열이 COLLATE 'en' 절로 생성된 경우 열의 데이터에 영어가 아닌 문자 É 가 포함될 수 있습니다. 이 상황에서 문자 ÉE 에 가깝게 정렬됩니다.

  • 반드시 의미가 있을 필요는 없는 데이터 정렬 작업을 지정할 수 있습니다.

    예를 들어, 독일어 데이터 정렬을 사용하여 폴란드어 데이터를 프랑스어 데이터와 비교하도록 지정할 수 있습니다.

    SELECT ... WHERE COLLATE(French_column, 'de') = Polish_column;
    
    Copy

    하지만 Snowflake는 예기치 않은 결과나 의도하지 않은 결과를 반환할 수 있으므로 이 기능을 이런 식으로 사용하지 않는 것이 좋습니다.

  • 테이블 열을 정의하고 나면 열에 대한 데이터 정렬을 변경할 수 없습니다. 다시 말해, CREATE TABLE 문을 사용하여 특정 데이터 정렬로 열을 만든 후에는 ALTER TABLE 을 사용하여 데이터 정렬을 변경할 수 없습니다.

    그러나 SELECT 문과 같이 열을 참조하는 DML 문에서 다른 데이터 정렬을 지정할 수 있습니다.

ciupper / lower 의 차이점

upperlower 데이터 정렬 사양은 문자열 비교 및 정렬 중에 ci 데이터 정렬 사양보다 더 나은 성능을 제공할 수 있습니다. 그러나 다음 섹션에 설명된 대로 upperlowerci 와는 약간 다른 효과를 미칩니다.

무시할 수 있는 코드 포인트 처리의 차이점

유니코드 데이터 정렬 알고리즘에서는 데이터 정렬 요소(코드 포인트)를 무시할 수 있는데, 이는 곧 문자열 비교 및 정렬 중에 코드 포인트가 고려되지 않는다는 의미입니다.

  • ci 데이터 정렬 사양을 사용하면 이러한 코드 포인트가 무시됩니다. 이로 인해 무시할 수 있는 코드 포인트를 검색하거나 바꾸기 어려워질 수 있습니다.

  • upperlower 데이터 정렬 사양을 사용하면 이러한 코드 포인트가 무시되지 않습니다.

예를 들어 코드 포인트 U+0001 은 무시할 수 있습니다. 이 코드 포인트를 en-ci 데이터 정렬 사양으로 빈 문자열과 비교하면 U+0001 이 무시되므로 결과는 TRUE입니다.

SELECT '\u0001' = '' COLLATE 'en-ci';
Copy
+-------------------------------+
| '\U0001' = '' COLLATE 'EN-CI' |
|-------------------------------|
| True                          |
+-------------------------------+

반면에 upper 또는 lower 데이터 정렬 사양을 사용하는 경우 U+0001 이 무시되지 않으므로 결과는 FALSE입니다.

SELECT '\u0001' = '' COLLATE 'upper';
Copy
+-------------------------------+
| '\U0001' = '' COLLATE 'UPPER' |
|-------------------------------|
| False                         |
+-------------------------------+

마찬가지로, REPLACE 함수를 호출하여 문자열에서 이 코드 포인트를 제거한다고 가정해 보겠습니다. en-ci 데이터 정렬 사양을 사용하는 경우 U+0001 이 무시되므로 이 함수는 코드 포인트를 제거하지 않습니다.

아래 예에서 볼 수 있듯이, REPLACE 함수가 반환하는 문자열은 이 함수가 U+0001 문자를 제거하지 않으므로 함수에 전달된 문자열과 길이가 동일합니다.

SELECT
  LEN('abc\u0001') AS original_length,
  LEN(REPLACE('abc\u0001' COLLATE 'en-ci', '\u0001')) AS length_after_replacement;
Copy
+-----------------+--------------------------+
| ORIGINAL_LENGTH | LENGTH_AFTER_REPLACEMENT |
|-----------------+--------------------------|
|               4 |                        4 |
+-----------------+--------------------------+

반면에, upper 또는 lower 데이터 정렬 사양을 사용하는 경우 이 함수는 문자열에서 코드 포인트를 제거하여 더 짧은 문자열을 반환합니다.

SELECT
  LEN('abc\u0001') AS original_length,
  LEN(REPLACE('abc\u0001' COLLATE 'upper', '\u0001')) AS length_after_replacement;
Copy
+-----------------+--------------------------+
| ORIGINAL_LENGTH | LENGTH_AFTER_REPLACEMENT |
|-----------------+--------------------------|
|               4 |                        3 |
+-----------------+--------------------------+

다른 코드 포인트로 문자를 표현할 때의 차이점

유니코드에서는 다른 코드 포인트 시퀀스가 동일한 문자를 나타낼 수 있습니다. 예를 들어, Dialytika 및 Tonos가 포함된 그리스 소문자 Iota는 코드 포인트 U+0390 으로 미리 구성된 문자 또는 분해된 문자에 대한 일련의 코드 포인트 U+03b9 U+0308 U+0301 의 시퀀스로 표시될 수 있습니다.

ci 데이터 정렬 사양을 사용하는 경우 문자에 대한 서로 다른 코드 포인트 시퀀스가 동일한 문자로 처리됩니다. 예를 들어, 코드 포인트 U+0390 과 코드 포인트 U+03b9 U+0308 U+0301 의 시퀀스는 동일한 것으로 처리됩니다.

SELECT '\u03b9\u0308\u0301' = '\u0390' COLLATE 'en-ci';
Copy
+-------------------------------------------------+
| '\U03B9\U0308\U0301' = '\U0390' COLLATE 'EN-CI' |
|-------------------------------------------------|
| True                                            |
+-------------------------------------------------+

upperlower 데이터 정렬 사양의 성능을 향상하기 위해 이 시퀀스는 동일한 방식으로 처리되지 않습니다. 두 개의 코드 포인트 시퀀스는 대문자나 소문자로 변환된 후 동일한 이진 표현으로 생성되는 경우에만 동일한 것으로 간주됩니다.

예를 들어, 코드 포인트 U+0390 및 코드 포인트 U+03b9 U+0308 U+0301 의 시퀀스와 함께 upper 사양을 사용하면 문자가 동일하게 처리됩니다.

SELECT '\u03b9\u0308\u0301' = '\u0390' COLLATE 'upper';
Copy
+-------------------------------------------------+
| '\U03B9\U0308\U0301' = '\U0390' COLLATE 'UPPER' |
|-------------------------------------------------|
| True                                            |
+-------------------------------------------------+

lower 사양을 사용하면 동일하지 않은 문자가 생성됩니다.

SELECT '\u03b9\u0308\u0301' = '\u0390' COLLATE 'lower';
Copy
+-------------------------------------------------+
| '\U03B9\U0308\U0301' = '\U0390' COLLATE 'LOWER' |
|-------------------------------------------------|
| False                                           |
+-------------------------------------------------+

100개 이상의 복합 소문자 코드 포인트에 비해 복합 대문자 코드 포인트(U+0130)가 하나만 있으므로 (lower 대신) upper 를 사용할 때 이러한 차이가 발생할 가능성이 적습니다.

단일 문자를 나타내는 코드 포인트 시퀀스와의 차이점

코드 포인트 시퀀스가 단일 문자를 나타내는 경우 ci 데이터 정렬 사양은 시퀀스가 단일 문자를 나타내고 시퀀스의 개별 코드 포인트와 일치하지 않는다는 점을 인식합니다.

예를 들어, 코드 포인트 U+03b9 U+0308 U+0301 의 시퀀스는 단일 문자(Dialytika 및 Tonos가 포함된 그리스 소문자 Iota)를 나타냅니다. U+0308U+0301U+03b9 에 적용된 악센트를 나타냅니다.

ci 데이터 정렬 사양의 경우 CONTAINS 함수를 사용하여 시퀀스 U+03b9 U+0308U+03b9 또는 U+0308 이 포함되어 있는지 확인하면 시퀀스 U+03b9 U+0308 이 단일 문자로 처리되므로 이 함수는 FALSE를 반환합니다.

SELECT CONTAINS('\u03b9\u0308', '\u03b9' COLLATE 'en-ci');
Copy
+----------------------------------------------------+
| CONTAINS('\U03B9\U0308', '\U03B9' COLLATE 'EN-CI') |
|----------------------------------------------------|
| False                                              |
+----------------------------------------------------+
SELECT CONTAINS('\u03b9\u0308', '\u0308' COLLATE 'en-ci');
Copy
+----------------------------------------------------+
| CONTAINS('\U03B9\U0308', '\U0308' COLLATE 'EN-CI') |
|----------------------------------------------------|
| False                                              |
+----------------------------------------------------+

성능을 개선하기 위해 upperlower 사양은 이러한 시퀀스를 단일 문자로 처리하지 않습니다. 위의 예에서 이러한 사양은 코드 포인트 시퀀스를 별도의 문자로 처리하므로 CONTAINS 함수는 TRUE를 반환합니다.

SELECT CONTAINS('\u03b9\u0308', '\u03b9' COLLATE 'upper');
Copy
+----------------------------------------------------+
| CONTAINS('\U03B9\U0308', '\U03B9' COLLATE 'UPPER') |
|----------------------------------------------------|
| True                                               |
+----------------------------------------------------+
SELECT CONTAINS('\u03b9\u0308', '\u0308' COLLATE 'upper');
Copy
+----------------------------------------------------+
| CONTAINS('\U03B9\U0308', '\U0308' COLLATE 'UPPER') |
|----------------------------------------------------|
| True                                               |
+----------------------------------------------------+

대/소문자 변경으로 여러 코드 포인트가 발생할 때의 차이점

일부 복합 문자의 경우 문자의 대문자 또는 소문자 버전이 일련의 코드 포인트로 표현됩니다. 예를 들어, 독일어 문자 ß의 대문자는 두 S 문자의 시퀀스(SS)입니다.

ß와 SS는 동일하지만 upper 데이터 정렬 사양을 사용하는 경우 ß 및 SS를 검색하면 다른 결과가 반환됩니다. 대/소문자 변환으로 생성된 시퀀스는 전체적으로 일치하거나 전혀 일치하지 않습니다.

SELECT CONTAINS('ß' , 's' COLLATE 'upper');
Copy
+--------------------------------------+
| CONTAINS('SS' , 'S' COLLATE 'UPPER') |
|--------------------------------------|
| False                                |
+--------------------------------------+
SELECT CONTAINS('ss', 's' COLLATE 'upper');
Copy
+-------------------------------------+
| CONTAINS('SS', 'S' COLLATE 'UPPER') |
|-------------------------------------|
| True                                |
+-------------------------------------+

정렬 순서의 차이점

upperlower 데이터 정렬 사양의 정렬은 ci 사양의 정렬과 다르게 작동합니다.

  • ci 사양을 사용하면 문자열이 데이터 정렬 키를 기준으로 정렬됩니다. 일반적으로 데이터 정렬 키는 대/소문자 구분, 악센트 구분, 로캘 등을 설명할 수 있습니다.

  • upperlower 사양을 사용하면 성능 향상을 위해 문자열이 코드 포인트를 기준으로 정렬됩니다.

예를 들어, ASCII 범위 내의 일부 문자(예: +-)는 다르게 정렬됩니다.

SELECT '+' < '-' COLLATE 'en-ci';
Copy
+---------------------------+
| '+' < '-' COLLATE 'EN-CI '|
|---------------------------|
| False                     |
+---------------------------+
SELECT '+' < '-' COLLATE 'upper';
Copy
+---------------------------+
| '+' < '-' COLLATE 'UPPER' |
|---------------------------|
| True                      |
+---------------------------+

또 다른 예로, 무시된 코드 포인트가 있는 문자열은 다른 순서로 정렬됩니다.

SELECT 'a\u0001b' < 'ab' COLLATE 'en-ci';
Copy
+-----------------------------------+
| 'A\U0001B' < 'AB' COLLATE 'EN-CI' |
|-----------------------------------|
| False                             |
+-----------------------------------+
SELECT 'a\u0001b' < 'ab' COLLATE 'upper';
Copy
+-----------------------------------+
| 'A\U0001B' < 'AB' COLLATE 'UPPER' |
|-----------------------------------|
| True                              |
+-----------------------------------+

또한 이모지는 다르게 정렬됩니다.

SELECT 'abc' < '❄' COLLATE 'en-ci';
Copy
+-----------------------------+
| 'ABC' < '❄' COLLATE 'EN-CI' |
|-----------------------------|
| False                       |
+-----------------------------+
SELECT 'abc' < '❄' COLLATE 'upper';
Copy
+-----------------------------+
| 'ABC' < '❄' COLLATE 'UPPER' |
|-----------------------------|
| True                        |
+-----------------------------+

데이터 정렬 제한 사항

데이터 정렬은 최대 8MB까지의 문자열에 대해서만 지원됨

Snowflake VARCHAR 데이터 타입은 최대 16MB의 문자열을 지원하지만, Snowflake는 결과 문자열이 8MB 이하일 때만 데이터 정렬을 지원합니다. (일부 데이터 정렬 작업에서는 문자열이 길어질 수 있습니다.)

데이터 정렬과 UDFs에 대한 제한 사항

Snowflake는 UDF(사용자 정의 함수)와의 데이터 정렬을 지원하지 않습니다.

  • UDF에서 조합된 문자열 값을 반환할 수 없습니다. 서버는 실제 반환 타입이 선언된 반환 타입과 호환되지 않는다는 메시지를 표시합니다.

  • 조합된 문자열 값을 UDF에 전달하면 조합 정보가 전달되지 않습니다. UDF는 문자열을 정렬되지 않은 문자열로 봅니다.

VARIANT, ARRAY 또는 OBJECT의 문자열에 대해 지원되지 않는 데이터 정렬

VARIANT, OBJECT 또는 ARRAY 내부에 저장된 문자열은 데이터 정렬 사양을 포함하지 않습니다. 따라서 다음과 같습니다.

  • 이러한 값의 비교에서는 항상 “utf8” 데이터 정렬을 사용합니다.

  • 데이터 정렬 사양이 있는 VARCHAR 값을 사용하여 ARRAY, OBJECT 또는 VARIANT 값을 생성할 때, 데이터 정렬 사양이 유지되지 않습니다.

  • 그래도 사용자는 값을 추출하고 VARCHAR로 캐스팅하고 데이터 정렬 사양을 추가하여 ARRAY, OBJECT 또는 VARIANT 내부에 저장된 값을 계속 비교할 수 있습니다. 예:

    COLLATE(VARIANT_COL:fld1::VARCHAR, 'en-ci') = VARIANT_COL:fld2::VARCHAR
    
    Copy

다음 문은 각 열에 대해 서로 다른 데이터 정렬을 사용하는 테이블을 생성합니다.

CREATE TABLE collation_demo (
  uncollated_phrase VARCHAR, 
  utf8_phrase VARCHAR COLLATE 'utf8',
  english_phrase VARCHAR COLLATE 'en',
  spanish_phrase VARCHAR COLLATE 'sp'
  );

INSERT INTO collation_demo (uncollated_phrase, utf8_phrase, english_phrase, spanish_phrase) 
   VALUES ('pinata', 'pinata', 'pinata', 'piñata');
Copy

테이블에 대한 다음 쿼리는 예상 값을 보여줍니다.

SELECT * FROM collation_demo;
+-------------------+-------------+----------------+----------------+
| UNCOLLATED_PHRASE | UTF8_PHRASE | ENGLISH_PHRASE | SPANISH_PHRASE |
|-------------------+-------------+----------------+----------------|
| pinata            | pinata      | pinata         | piñata         |
+-------------------+-------------+----------------+----------------+
Copy

다음 쿼리는 문자 ñn 과 일치하지 않으므로 일치하는 항목을 찾지 못합니다.

SELECT * FROM collation_demo WHERE spanish_phrase = uncollated_phrase;
+-------------------+-------------+----------------+----------------+
| UNCOLLATED_PHRASE | UTF8_PHRASE | ENGLISH_PHRASE | SPANISH_PHRASE |
|-------------------+-------------+----------------+----------------|
+-------------------+-------------+----------------+----------------+
Copy

데이터 정렬을 변경해도 관계는 있지만 같지는 않은 문자(예: ñn)를 같은 것으로 취급하도록 강제하지는 못합니다.

SELECT * FROM collation_demo 
    WHERE spanish_phrase = uncollated_phrase COLLATE 'sp';
+-------------------+-------------+----------------+----------------+
| UNCOLLATED_PHRASE | UTF8_PHRASE | ENGLISH_PHRASE | SPANISH_PHRASE |
|-------------------+-------------+----------------+----------------|
+-------------------+-------------+----------------+----------------+
Copy

다음 예는 정렬 순서에 미치는 데이터 정렬의 효과를 보여줍니다.

INSERT INTO collation_demo (spanish_phrase) VALUES
   ('piña colada'),
   ('Pinatubo (Mount)'),
   ('pint'),
   ('Pinta');
Copy
SELECT spanish_phrase FROM collation_demo 
  ORDER BY spanish_phrase;
+------------------+
| SPANISH_PHRASE   |
|------------------|
| piña colada      |
| piñata           |
| Pinatubo (Mount) |
| pint             |
| Pinta            |
+------------------+
Copy

다음 쿼리는 데이터 정렬을 ‘sp’(스페인어)에서 ‘utf8’로 변경하여 ñn 의 순서를 반대로 바꿉니다.

SELECT spanish_phrase FROM collation_demo 
  ORDER BY COLLATE(spanish_phrase, 'utf8');
+------------------+
| SPANISH_PHRASE   |
|------------------|
| Pinatubo (Mount) |
| Pinta            |
| pint             |
| piña colada      |
| piñata           |
+------------------+
Copy

이 예에서는 COLLATION 함수를 사용하여 열과 같은 식의 데이터 정렬을 보는 방법을 보여줍니다.

CREATE TABLE collation_demo2 (c1 VARCHAR COLLATE 'fr', c2 VARCHAR COLLATE '');
INSERT INTO collation_demo2 (c1, c2) VALUES
    ('a', 'a'),
    ('b', 'b');
Copy
SELECT DISTINCT COLLATION(c1), COLLATION(c2) FROM collation_demo2;
+---------------+---------------+
| COLLATION(C1) | COLLATION(C2) |
|---------------+---------------|
| fr            | NULL          |
+---------------+---------------+
Copy

DESCRIBE TABLE 을 사용하여 테이블의 열에 대한 데이터 정렬 정보를 볼 수도 있습니다.

DESC TABLE collation_demo2;
+------+--------------------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+ 
| name | type                           | kind   | null? | default | primary key | unique key | check | expression | comment | policy name |
|------+--------------------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------|
| C1   | VARCHAR(16777216) COLLATE 'fr' | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        |
| C2   | VARCHAR(16777216)              | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        |
+------+--------------------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+
Copy