> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8a08bda2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> ClickHouse 中 Tuple 数据类型的文档

# Tuple(T1, T2, ...)

Tuple 是由多个元素组成的元组，其中每个元素都有各自的[类型](/zh/reference/data-types)。Tuple 必须至少包含一个元素。

Tuple 用于临时对列进行分组。在查询中使用 IN 表达式时，可以对列进行分组；Tuple 还可用于指定 lambda 函数的某些形式参数。更多信息，请参见 [IN 运算符](/zh/reference/statements/in) 和 [高阶函数](/zh/reference/functions/regular-functions/overview#higher-order-functions) 部分。

Tuple 可以作为查询结果返回。在这种情况下，对于 JSON 以外的文本格式，其值以逗号分隔并放在 `()` 中。在 JSON 格式中，Tuple 会以数组形式输出 (使用 `[]`) 。

<div id="creating-tuples">
  ## 创建 Tuple
</div>

您可以使用函数创建 Tuple：

```sql theme={null}
tuple(T1, T2, ...)
```

创建 Tuple 的示例：

```sql theme={null}
SELECT tuple(1, 'a') AS x, toTypeName(x)
```

```text theme={null}
┌─x───────┬─toTypeName(tuple(1, 'a'))─┐
│ (1,'a') │ Tuple(UInt8, String)      │
└─────────┴───────────────────────────┘
```

Tuple 可以只包含一个元素

示例：

```sql theme={null}
SELECT tuple('a') AS x;
```

```text theme={null}
┌─x─────┐
│ ('a') │
└───────┘
```

语法 `(tuple_element1, tuple_element2)` 可用于创建由多个元素组成的Tuple，无需调用 `tuple()` 函数。

示例：

```sql theme={null}
SELECT (1, 'a') AS x, (today(), rand(), 'someString') AS y, ('a') AS not_a_tuple;
```

```text theme={null}
┌─x───────┬─y──────────────────────────────────────┬─not_a_tuple─┐
│ (1,'a') │ ('2022-09-21',2006973416,'someString') │ a           │
└─────────┴────────────────────────────────────────┴─────────────┘
```

<div id="data-type-detection">
  ## 数据类型检测
</div>

在动态创建Tuple时，ClickHouse 会将Tuple参数的类型推断为能够容纳给定参数值的最小类型。如果该值为 [NULL](/zh/reference/settings/formats#input_format_null_as_default)，则推断出的类型为 [Nullable](/zh/reference/data-types/nullable)。

自动检测数据类型的示例：

```sql theme={null}
SELECT tuple(1, NULL) AS x, toTypeName(x)
```

```text theme={null}
┌─x─────────┬─toTypeName(tuple(1, NULL))──────┐
│ (1, NULL) │ Tuple(UInt8, Nullable(Nothing)) │
└───────────┴─────────────────────────────────┘
```

<div id="referring-to-tuple-elements">
  ## 引用 Tuple 中的元素
</div>

可以按名称或索引引用 Tuple 中的元素：

```sql title="Query" theme={null}
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; -- 按名称
SELECT a.2 FROM named_tuples; -- 按索引
```

```text title="Response" theme={null}
┌─a.s─┐
│ y   │
│ x   │
└─────┘

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

<div id="comparison-operations-with-tuple">
  ## Tuple 的比较运算
</div>

比较两个 Tuple 时，会按从左到右的顺序依次比较各个元素。如果第一个 Tuple 的某个元素大于 (小于) 第二个 Tuple 中对应的元素，则第一个 Tuple 大于 (小于) 第二个 Tuple；否则 (即这两个元素相等) ，继续比较下一个元素。

示例：

```sql theme={null}
SELECT (1, 'z') > (1, 'a') c1, (2022, 01, 02) > (2023, 04, 02) c2, (1,2,3) = (3,2,1) c3;
```

```text theme={null}
┌─c1─┬─c2─┬─c3─┐
│  1 │  0 │  0 │
└────┴────┴────┘
```

实际应用示例：

```sql theme={null}
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 │
└─────┴──────────┴───────┘

-- 查找每个 key 对应 duration 最大的 value，若 duration 相等则取最大的 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 │
└─────┴───────────────┴───────────────────────────────────────┘
```

<div id="nullable-tuple">
  ## Nullable(Tuple(T1, T2, ...))
</div>

<Warning>
  **Experimental 功能**

  需要设置 `SET allow_experimental_nullable_tuple_type = 1`
  这是一个实验性功能，未来版本中可能会发生变化。
</Warning>

允许整个 Tuple 为 `NULL`，而不是像 `Tuple(Nullable(T1), Nullable(T2), ...)` 那样只能让各个单独元素为 `NULL`。

| 类型                                         | Tuple 可为 NULL | 元素可为 NULL |
| ------------------------------------------ | ------------- | --------- |
| `Nullable(Tuple(String, Int64))`           | ✅             | ❌         |
| `Tuple(Nullable(String), Nullable(Int64))` | ❌             | ✅         |

示例：

```sql theme={null}
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;
```

```txt theme={null}
 ┌─id─┬─data─┐
 │  2 │ ᴺᵁᴸᴸ │
 └────┴──────┘
```
