각 요소가 개별 타입을 가지는 요소들의 Tuple입니다. Tuple은 최소 하나의 요소를 포함해야 합니다.
Tuple은 임시 컬럼 그룹화에 사용됩니다. 쿼리에서 IN 표현식을 사용할 때 컬럼을 그룹화할 수 있고, 람다 함수의 특정 형식 매개변수를 지정할 때 사용할 수 있습니다. 자세한 내용은 IN 연산자와 고차 함수 섹션을 참조하십시오.
Tuple은 쿼리 결과가 될 수 있습니다. 이 경우 JSON 이외의 텍스트 포맷에서는 값이 괄호 안에서 쉼표로 구분되어 표시됩니다. JSON 포맷에서는 Tuple이 배열(대괄호 안)로 출력됩니다.
Tuple 생성
함수를 사용하여 Tuple을 생성할 수 있습니다.
튜플 생성 예시:
SELECT tuple(1, 'a') AS x, toTypeName(x)
┌─x───────┬─toTypeName(tuple(1, 'a'))─┐
│ (1,'a') │ Tuple(UInt8, String) │
└─────────┴───────────────────────────┘
Tuple은 단일 요소만 포함할 수도 있습니다
예시:
┌─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 │
└─────────┴────────────────────────────────────────┴─────────────┘
데이터 타입 감지
튜플을 동적으로 생성할 때 ClickHouse는 각 튜플 인자로 전달된 값을 담을 수 있는 가장 작은 데이터 타입으로 인자의 타입을 추론합니다. 값이 NULL인 경우, 추론되는 타입은 널 허용입니다.
자동 데이터 타입 감지 예시는 다음과 같습니다:
SELECT tuple(1, NULL) AS x, toTypeName(x)
┌─x─────────┬─toTypeName(tuple(1, NULL))──────┐
│ (1, NULL) │ Tuple(UInt8, Nullable(Nothing)) │
└───────────┴─────────────────────────────────┘
Tuple 요소 참조
Tuple 요소는 이름 또는 인덱스를 통해 참조할 수 있습니다.
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의 비교 연산
두 Tuple은 왼쪽에서 오른쪽 순서로 각 요소를 차례대로 비교합니다. 첫 번째 Tuple의 요소가 두 번째 Tuple의 해당 요소보다 크면(또는 작으면), 첫 번째 Tuple이 두 번째 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, ...))
실험적 기능
SET allow_experimental_nullable_tuple_type = 1 설정이 필요합니다.
이는 실험적 기능이며, 향후 버전에서 변경될 수 있습니다.
Tuple(Nullable(T1), Nullable(T2), ...)에서 개별 요소만 NULL이 될 수 있는 것과 달리, 전체 Tuple이 NULL이 될 수 있도록 합니다.
| Type | Tuple이 NULL일 수 있음 | 요소가 NULL일 수 있음 |
|---|
Nullable(Tuple(String, Int64)) | ✅ | ❌ |
Tuple(Nullable(String), Nullable(Int64)) | ❌ | ✅ |
예시:
SET allow_experimental_nullable_tuple_type = 1;
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 │ ᴺᵁᴸᴸ │
└────┴──────┘