Tuple 데이터 타입

Tuple 데이터 타입

각각 개별 타입을 가진 요소들의 튜플이에요. Tuple은 적어도 하나의 요소를 포함해야 해요. 튜플은 임시 컬럼 그룹화에 사용돼요.

출처: 문서

본문

각각 개별 타입을 가진 요소들의 튜플이에요. Tuple은 적어도 하나의 요소를 포함해야 해요. 튜플은 임시 컬럼 그룹화에 사용돼요. 쿼리에서 IN 표현식이 사용될 때 컬럼을 그룹화할 수 있고, 람다 함수의 특정 형식 매개변수를 지정할 때도 사용돼요. 자세한 내용은 IN 연산자고차 함수(Higher order functions) 섹션을 참고해요. 튜플은 쿼리의 결과가 될 수 있어요. 이 경우 JSON이 아닌 텍스트 형식에서는 값들이 () 안에 쉼표로 구분돼요. JSON 형식에서는 튜플이 배열(안에 [])로 출력돼요.

튜플 만들기 (Creating Tuples)

함수를 사용해 튜플을 만들 수 있어요.

tuple(T1, T2, ...)

튜플 생성 예시:

SELECT tuple(1, 'a') AS x, toTypeName(x)
┌─x───────┬─toTypeName(tuple(1, 'a'))─┐
│ (1,'a') │ Tuple(UInt8, String)      │
└─────────┴───────────────────────────┘

Tuple은 단일 요소를 담을 수 있어요. 예시:

SELECT tuple('a') AS x;
┌─x─────┐
│ ('a') │
└───────┘

(tuple_element1, tuple_element2) 문법으로 tuple() 함수를 호출하지 않고 여러 요소의 튜플을 만들 수 있어요. 예시:

SELECT (1, 'a') AS x, (today(), rand(), 'someString') AS y, ('a') AS not_a_tuple;
┌─x───────┬─y──────────────────────────────────────┬─not_a_tuple─┐
│ (1,'a') │ ('2022-09-21',2006973416,'someString') │ a           │
└─────────┴────────────────────────────────────────┴─────────────┘

데이터 타입 감지 (Data Type Detection)

튜플을 즉석에서 만들 때 ClickHouse는 제공된 인자 값을 담을 수 있는 가장 작은 타입으로 튜플 인자의 타입을 추론해요. 값이 NULL이면 추론된 타입은 Nullable이에요. 자동 데이터 타입 감지 예시:

SELECT tuple(1, NULL) AS x, toTypeName(x)
┌─x─────────┬─toTypeName(tuple(1, NULL))──────┐
│ (1, NULL) │ Tuple(UInt8, Nullable(Nothing)) │
└───────────┴─────────────────────────────────┘

Tuple 요소 참조 (Referring to Tuple Elements)

튜플 요소는 이름 또는 인덱스로 참조할 수 있어요. 쿼리:

CREATE TABLE named_tuples (`a` Tuple(s String, i Int64)) ENGINE = Memory;
INSERT INTO named_tuples VALUES (('y', 10)), (('x',-10));

SELECT a.s FROM named_tuples; -- by name
SELECT a.2 FROM named_tuples; -- by index

응답:

┌─a.s─┐
│ y   │
│ x   │
└─────┘

┌─tupleElement(a, 2)─┐
│                 10 │
│                -10 │
└────────────────────┘

Tuple과의 비교 연산 (Comparison operations with Tuple)

두 튜플은 왼쪽에서 오른쪽으로 요소들을 순차 비교하여 비교돼요. 첫 튜플의 요소가 두 번째 튜플의 대응 요소보다 크면(작으면) 첫 튜플이 두 번째보다 큰(작은) 것이고, 그렇지 않으면(두 요소가 같으면) 다음 요소가 비교돼요. 예시:

SELECT (1, 'z') > (1, 'a') c1, (2022, 01, 02) > (2023, 04, 02) c2, (1,2,3) = (3,2,1) c3;
┌─c1─┬─c2─┬─c3─┐
│  1 │  0 │  0 │
└────┴────┴────┘

실제 예시:

CREATE TABLE test
(
    `year` Int16,
    `month` Int8,
    `day` Int8
)
ENGINE = Memory AS
SELECT *
FROM values((2022, 12, 31), (2000, 1, 1));

SELECT * FROM test;

┌─year─┬─month─┬─day─┐
│ 2022 │    12 │  31 │
│ 2000 │     1 │   1 │
└──────┴───────┴─────┘

SELECT *
FROM test
WHERE (year, month, day) > (2010, 1, 1);

┌─year─┬─month─┬─day─┐
│ 2022 │    12 │  31 │
└──────┴───────┴─────┘
CREATE TABLE test
(
    `key` Int64,
    `duration` UInt32,
    `value` Float64
)
ENGINE = Memory AS
SELECT *
FROM values((1, 42, 66.5), (1, 42, 70), (2, 1, 10), (2, 2, 0));

SELECT * FROM test;

┌─key─┬─duration─┬─value─┐
│   1 │       42 │  66.5 │
│   1 │       42 │    70 │
│   2 │        1 │    10 │
│   2 │        2 │     0 │
└─────┴──────────┴───────┘

-- Let's find a value for each key with the biggest duration, if durations are equal, select the biggest value

SELECT
    key,
    max(duration),
    argMax(value, (duration, value))
FROM test
GROUP BY key
ORDER BY key ASC;

┌─key─┬─max(duration)─┬─argMax(value, tuple(duration, value))─┐
│   1 │            42 │                                    70 │
│   2 │             2 │                                     0 │
└─────┴───────────────┴───────────────────────────────────────┘

Nullable(Tuple(T1, T2, …))

Tuple(Nullable(T1), Nullable(T2), ...)(개별 요소만 NULL일 수 있음)와 달리 전체 튜플이 NULL이 될 수 있게 해줘요.

타입 Tuple이 NULL일 수 있음 요소가 NULL일 수 있음
Nullable(Tuple(String, Int64))
Tuple(Nullable(String), Nullable(Int64))

예시:

CREATE TABLE test (
    id UInt32,
    data Nullable(Tuple(String, Int64))
) ENGINE = Memory;

INSERT INTO test VALUES (1, ('hello', 42)), (2, NULL);

SELECT * FROM test WHERE data IS NULL;
┌─id─┬─data─┐
│  2 │ ᴺᵁᴸᴸ │
└────┴──────┘

더 알아보기 (Learn more)