> ## 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.

> ORDER BY 절 문서

# ORDER BY 절

`ORDER BY` 절에는 다음이 포함될 수 있습니다.

* 표현식 목록(예: `ORDER BY visits, search_phrase`)
* `SELECT` 절의 컬럼을 가리키는 숫자 목록(예: `ORDER BY 2, 1`) 또는
* `SELECT` 절의 모든 컬럼을 의미하는 `ALL`(예: `ORDER BY ALL`)

컬럼 번호 기준 정렬을 비활성화하려면 [enable\_positional\_arguments](/ko/reference/settings/session-settings#enable_positional_arguments) 설정을 0으로 지정하세요.
`ALL` 기준 정렬을 비활성화하려면 [enable\_order\_by\_all](/ko/reference/settings/session-settings#enable_order_by_all) 설정을 0으로 지정하세요.

`ORDER BY` 절에는 정렬 방향을 지정하는 `DESC`(내림차순) 또는 `ASC`(오름차순) 수정자를 사용할 수 있습니다.
정렬 순서를 명시적으로 지정하지 않으면 기본적으로 `ASC`가 사용됩니다.
정렬 방향은 전체 목록이 아니라 개별 표현식에 적용됩니다. 예를 들어 `ORDER BY Visits DESC, SearchPhrase`와 같습니다.
또한 정렬은 대소문자를 구분하여 수행됩니다.

정렬 표현식 값이 동일한 행은 임의적이며 비결정적인 순서로 반환됩니다.
`SELECT` SQL 문에서 `ORDER BY` 절을 생략한 경우에도 행의 순서는 임의적이며 비결정적입니다.

<div id="sorting-of-special-values">
  ## 특수 값의 정렬
</div>

`NaN` 및 `NULL`의 정렬 순서에는 두 가지 방식이 있습니다.

* 기본값 또는 `NULLS LAST` 수정자를 사용하는 경우: 일반 값이 먼저 오고, 그다음 `NaN`, 마지막으로 `NULL`이 옵니다.
* `NULLS FIRST` 수정자를 사용하는 경우: `NULL`이 먼저 오고, 그다음 `NaN`, 마지막으로 다른 값이 옵니다.

<div id="example">
  ### 예시
</div>

테이블에 대해

```text theme={null}
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 2 │    2 │
│ 1 │  nan │
│ 2 │    2 │
│ 3 │    4 │
│ 5 │    6 │
│ 6 │  nan │
│ 7 │ ᴺᵁᴸᴸ │
│ 6 │    7 │
│ 8 │    9 │
└───┴──────┘
```

다음을 확인하려면 쿼리 `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST`를 실행하십시오:

```text theme={null}
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 7 │ ᴺᵁᴸᴸ │
│ 1 │  nan │
│ 6 │  nan │
│ 2 │    2 │
│ 2 │    2 │
│ 3 │    4 │
│ 5 │    6 │
│ 6 │    7 │
│ 8 │    9 │
└───┴──────┘
```

부동소수점 수를 정렬할 때 NaN은 다른 값과 별도로 취급됩니다. 정렬 순서와 관계없이 NaN은 항상 끝에 위치합니다. 다시 말해, 오름차순 정렬에서는 다른 모든 수보다 큰 것처럼 배치되고, 내림차순 정렬에서는 나머지 값보다 작은 것처럼 배치됩니다.

<div id="collation-support">
  ## Collation 지원
</div>

[String](/ko/reference/data-types/string) 값으로 정렬할 때는 collation(비교 규칙)을 지정할 수 있습니다. 예시: `ORDER BY SearchPhrase COLLATE 'tr'` - 문자열이 UTF-8 encoded라고 가정할 때, 터키어 알파벳을 사용하여 키워드를 오름차순으로 정렬하며 대소문자는 구분하지 않습니다. `COLLATE`는 ORDER BY의 각 표현식마다 독립적으로 지정하거나 생략할 수 있습니다. `ASC` 또는 `DESC`를 지정하는 경우 `COLLATE`는 그 뒤에 지정합니다. `COLLATE`를 사용하면 정렬은 항상 대소문자를 구분하지 않습니다.

`COLLATE`는 [LowCardinality](/ko/reference/data-types/lowcardinality), [널 허용](/ko/reference/data-types/nullable), [배열](/ko/reference/data-types/array), [Tuple](/ko/reference/data-types/tuple)에서 지원됩니다.

`COLLATE`를 사용한 정렬은 일반적인 바이트 기준 정렬보다 효율이 낮으므로, 소수의 행을 최종 정렬할 때만 사용하는 것을 권장합니다.

<div id="collation-examples">
  ## Collation 예시
</div>

[String](/ko/reference/data-types/string) 값만 포함된 예시:

입력 테이블:

```text theme={null}
┌─x─┬─s────┐
│ 1 │ bca  │
│ 2 │ ABC  │
│ 3 │ 123a │
│ 4 │ abc  │
│ 5 │ BCA  │
└───┴──────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```text title="Response" theme={null}
┌─x─┬─s────┐
│ 3 │ 123a │
│ 4 │ abc  │
│ 2 │ ABC  │
│ 1 │ bca  │
│ 5 │ BCA  │
└───┴──────┘
```

[널 허용](/ko/reference/data-types/nullable) 예시:

입력 테이블:

```text theme={null}
┌─x─┬─s────┐
│ 1 │ bca  │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │ ABC  │
│ 4 │ 123a │
│ 5 │ abc  │
│ 6 │ ᴺᵁᴸᴸ │
│ 7 │ BCA  │
└───┴──────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```text title="Response" theme={null}
┌─x─┬─s────┐
│ 4 │ 123a │
│ 5 │ abc  │
│ 3 │ ABC  │
│ 1 │ bca  │
│ 7 │ BCA  │
│ 6 │ ᴺᵁᴸᴸ │
│ 2 │ ᴺᵁᴸᴸ │
└───┴──────┘
```

[배열](/ko/reference/data-types/array) 예시:

입력 테이블:

```text theme={null}
┌─x─┬─s─────────────┐
│ 1 │ ['Z']         │
│ 2 │ ['z']         │
│ 3 │ ['a']         │
│ 4 │ ['A']         │
│ 5 │ ['z','a']     │
│ 6 │ ['z','a','a'] │
│ 7 │ ['']          │
└───┴───────────────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```text title="Response" theme={null}
┌─x─┬─s─────────────┐
│ 7 │ ['']          │
│ 3 │ ['a']         │
│ 4 │ ['A']         │
│ 2 │ ['z']         │
│ 5 │ ['z','a']     │
│ 6 │ ['z','a','a'] │
│ 1 │ ['Z']         │
└───┴───────────────┘
```

[LowCardinality](/ko/reference/data-types/lowcardinality) 문자열을 사용하는 예시:

입력 테이블:

```response theme={null}
┌─x─┬─s───┐
│ 1 │ Z   │
│ 2 │ z   │
│ 3 │ a   │
│ 4 │ A   │
│ 5 │ za  │
│ 6 │ zaa │
│ 7 │     │
└───┴─────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```response title="Response" theme={null}
┌─x─┬─s───┐
│ 7 │     │
│ 3 │ a   │
│ 4 │ A   │
│ 2 │ z   │
│ 1 │ Z   │
│ 5 │ za  │
│ 6 │ zaa │
└───┴─────┘
```

[Tuple](/ko/reference/data-types/tuple) 예시:

```response title="Response" theme={null}
┌─x─┬─s───────┐
│ 1 │ (1,'Z') │
│ 2 │ (1,'z') │
│ 3 │ (1,'a') │
│ 4 │ (2,'z') │
│ 5 │ (1,'A') │
│ 6 │ (2,'Z') │
│ 7 │ (2,'A') │
└───┴─────────┘
```

```sql title="Query" theme={null}
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
```

```response title="Response" theme={null}
┌─x─┬─s───────┐
│ 3 │ (1,'a') │
│ 5 │ (1,'A') │
│ 2 │ (1,'z') │
│ 1 │ (1,'Z') │
│ 7 │ (2,'A') │
│ 4 │ (2,'z') │
│ 6 │ (2,'Z') │
└───┴─────────┘
```

<div id="implementation-details">
  ## 구현 세부 사항
</div>

`ORDER BY`와 함께 충분히 작은 [LIMIT](/ko/reference/statements/select/limit)를 지정하면 RAM 사용량을 줄일 수 있습니다. 그렇지 않으면 정렬에 사용되는 메모리 양은 정렬할 데이터의 양에 비례합니다. 분산 쿼리 처리에서는 [GROUP BY](/ko/reference/statements/select/group-by)를 생략할 경우 정렬의 일부가 원격 서버에서 수행되고, 결과는 요청을 보낸 서버에서 머지됩니다. 즉, 분산 정렬에서는 정렬해야 하는 데이터 양이 단일 서버의 메모리 용량보다 클 수 있습니다.

RAM이 충분하지 않으면 외부 메모리(external memory)에서 정렬을 수행할 수 있습니다(디스크에 임시 파일 생성). 이를 위해 `max_bytes_before_external_sort` 설정을 사용하십시오. 이 값이 0(기본값)으로 설정되어 있으면 외부 정렬은 비활성화됩니다. 이 기능을 활성화하면 정렬할 데이터 양이 지정된 바이트 수에 도달할 때 수집된 데이터를 정렬한 뒤 임시 파일에 덤프합니다. 모든 데이터를 읽고 나면 정렬된 모든 파일을 머지하여 결과를 출력합니다. 파일은 설정의 `/var/lib/clickhouse/tmp/` 디렉터리에 기록됩니다(기본값이며, `tmp_path` 매개변수를 사용해 이 설정을 변경할 수 있습니다). 또한 쿼리가 메모리 제한을 초과하는 경우에만 디스크로 스필을 사용하도록 설정할 수도 있습니다. 즉, `max_bytes_ratio_before_external_sort=0.6`으로 설정하면 쿼리가 메모리 제한(사용자/서버)의 `60%`에 도달했을 때만 디스크로 스필이 활성화됩니다.

쿼리를 실행할 때 `max_bytes_before_external_sort`보다 더 많은 메모리를 사용할 수 있습니다. 따라서 이 설정값은 `max_memory_usage`보다 충분히 작아야 합니다. 예를 들어 서버에 RAM이 128 GB 있고 단일 쿼리 하나를 실행해야 한다면 `max_memory_usage`를 100 GB로, `max_bytes_before_external_sort`를 80 GB로 설정하십시오.

외부 정렬은 RAM에서 수행하는 정렬보다 훨씬 덜 효율적입니다.

<div id="optimization-of-data-reading">
  ## 데이터 읽기 최적화
</div>

`ORDER BY` 표현식에 테이블 정렬 키와 일치하는 접두사가 있으면 [optimize\_read\_in\_order](/ko/reference/settings/session-settings#optimize_read_in_order) 설정을 사용해 쿼리를 최적화할 수 있습니다.

`optimize_read_in_order` 설정이 활성화되면 ClickHouse 서버는 테이블 인덱스를 사용해 `ORDER BY` 키 순서대로 데이터를 읽습니다. 이렇게 하면 [LIMIT](/ko/reference/statements/select/limit)가 지정된 경우 모든 데이터를 읽지 않아도 됩니다. 따라서 LIMIT가 작은 대용량 데이터 쿼리를 더 빠르게 처리할 수 있습니다.

이 최적화는 `ASC`와 `DESC` 모두에서 동작하며, [GROUP BY](/ko/reference/statements/select/group-by) 절 및 [FINAL](/ko/reference/statements/select/from#final-modifier) 수정자와는 함께 사용할 수 없습니다.

`optimize_read_in_order` 설정이 비활성화되면 ClickHouse 서버는 `SELECT` 쿼리를 처리하는 동안 테이블 인덱스를 사용하지 않습니다.

`ORDER BY` 절이 있고 `LIMIT`이 크며, 조회 대상 데이터를 찾기 전에 매우 많은 레코드를 읽어야 하는 [WHERE](/ko/reference/statements/select/where) 조건이 있는 쿼리를 실행할 때는 `optimize_read_in_order`를 수동으로 비활성화하는 것이 좋습니다.

이 최적화는 다음 테이블 엔진에서 지원됩니다.

* [MergeTree](/ko/reference/engines/table-engines/mergetree-family/mergetree) ( [구체화된 뷰(Materialized View)](/ko/reference/statements/create/view#materialized-view) 포함),
* [Merge](/ko/reference/engines/table-engines/special/merge),
* [Buffer](/ko/reference/engines/table-engines/special/buffer)

`MaterializedView` 엔진 테이블에서는 `SELECT ... FROM merge_tree_table ORDER BY pk`와 같은 뷰에서 이 최적화가 동작합니다. 하지만 뷰 쿼리에 `ORDER BY` 절이 없으면 `SELECT ... FROM view ORDER BY pk`와 같은 쿼리에서는 지원되지 않습니다.

<div id="order-by-expr-with-fill-modifier">
  ## ORDER BY Expr WITH FILL 수정자
</div>

이 수정자는 [LIMIT ... WITH TIES modifier](/ko/reference/statements/select/limit#limit--with-ties-modifier)와 함께 사용할 수도 있습니다.

`WITH FILL` 수정자는 `ORDER BY expr` 뒤에 지정할 수 있으며, 필요에 따라 `FROM expr`, `TO expr`, `STEP expr` 매개변수를 함께 사용할 수 있습니다.
`expr` 컬럼에서 누락된 모든 값은 순차적으로 채워지며, 다른 컬럼은 기본값으로 채워집니다.

여러 컬럼을 채우려면 `ORDER BY` 섹션에서 각 필드 이름 뒤에 선택적 매개변수와 함께 `WITH FILL` 수정자를 추가하십시오.

```sql title="Query" theme={null}
ORDER BY expr [WITH FILL] [FROM const_expr] [TO const_expr] [STEP const_numeric_expr] [STALENESS const_numeric_expr], ... exprN [WITH FILL] [FROM expr] [TO expr] [STEP numeric_expr] [STALENESS numeric_expr]
[INTERPOLATE [(col [AS expr], ... colN [AS exprN])]]
```

`WITH FILL`은 Numeric(모든 종류의 float, decimal, int) 또는 Date/DateTime 타입의 필드에 적용할 수 있습니다. `String` 필드에 적용하면 누락된 값은 빈 문자열로 채워집니다.
`FROM const_expr`가 정의되지 않으면 채우기 시퀀스는 `ORDER BY`의 `expr` 필드 최솟값을 사용합니다.
`TO const_expr`가 정의되지 않으면 채우기 시퀀스는 `ORDER BY`의 `expr` 필드 최댓값을 사용합니다.
`STEP const_numeric_expr`가 정의되면 `const_numeric_expr`는 숫자 타입에서는 `as is`로, Date 타입에서는 `days`로, DateTime 타입에서는 `seconds`로 해석됩니다. 또한 시간 및 날짜 인터벌을 나타내는 [INTERVAL](/ko/reference/data-types/special-data-types/interval) 데이터 타입도 지원합니다.
`STEP const_numeric_expr`를 생략하면 채우기 시퀀스는 숫자 타입에는 `1.0`, Date 타입에는 `1 day`, DateTime 타입에는 `1 second`를 사용합니다.
`STALENESS const_numeric_expr`가 정의되면 원본 데이터에서 이전 행과의 차이가 `const_numeric_expr`를 초과할 때까지 쿼리가 행을 생성합니다.
`INTERPOLATE`는 `ORDER BY WITH FILL`에 포함되지 않는 컬럼에 적용할 수 있습니다. 이러한 컬럼은 이전 필드 값을 기준으로 `expr`를 적용해 채워집니다. `expr`가 없으면 이전 값을 반복합니다. 목록을 생략하면 허용되는 모든 컬럼이 포함됩니다.

`WITH FILL`이 없는 쿼리 예시:

```sql title="Query" theme={null}
SELECT n, source FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n;
```

```text title="Response" theme={null}
┌─n─┬─source───┐
│ 1 │ original │
│ 4 │ original │
│ 7 │ original │
└───┴──────────┘
```

`WITH FILL` 수정자를 적용한 동일한 쿼리:

```sql title="Query" theme={null}
SELECT n, source FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;
```

```text title="Response" theme={null}
┌───n─┬─source───┐
│   0 │          │
│ 0.5 │          │
│   1 │ original │
│ 1.5 │          │
│   2 │          │
│ 2.5 │          │
│   3 │          │
│ 3.5 │          │
│   4 │ original │
│ 4.5 │          │
│   5 │          │
│ 5.5 │          │
│   7 │ original │
└─────┴──────────┘
```

여러 필드에 대해 `ORDER BY field2 WITH FILL, field1 WITH FILL`을 사용하는 경우, 채우기 순서는 `ORDER BY` 절에 지정된 필드 순서를 따릅니다.

예시:

```sql title="Query" theme={null}
SELECT
    toDate((number * 10) * 86400) AS d1,
    toDate(number * 86400) AS d2,
    'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
    d2 WITH FILL,
    d1 WITH FILL STEP 5;
```

```text title="Response" theme={null}
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-01 │ 1970-01-03 │          │
│ 1970-01-01 │ 1970-01-04 │          │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-01-01 │ 1970-01-06 │          │
│ 1970-01-01 │ 1970-01-07 │          │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
```

필드 `d1`은 채워지지 않고 기본값도 사용되지 않습니다. 이는 `d2` 값에 반복값이 없어 `d1`의 시퀀스를 올바르게 계산할 수 없기 때문입니다.

다음은 `ORDER BY`의 필드를 변경한 쿼리입니다:

```sql title="Query" theme={null}
SELECT
    toDate((number * 10) * 86400) AS d1,
    toDate(number * 86400) AS d2,
    'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
    d1 WITH FILL STEP 5,
    d2 WITH FILL;
```

```text title="Response" theme={null}
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-16 │ 1970-01-01 │          │
│ 1970-01-21 │ 1970-01-01 │          │
│ 1970-01-26 │ 1970-01-01 │          │
│ 1970-01-31 │ 1970-01-01 │          │
│ 1970-02-05 │ 1970-01-01 │          │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-15 │ 1970-01-01 │          │
│ 1970-02-20 │ 1970-01-01 │          │
│ 1970-02-25 │ 1970-01-01 │          │
│ 1970-03-02 │ 1970-01-01 │          │
│ 1970-03-07 │ 1970-01-01 │          │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
```

다음 쿼리는 `d1` 컬럼에서 채워지는 각 값에 대해 1일 `INTERVAL` 데이터 타입을 사용합니다:

```sql title="Query" theme={null}
SELECT
    toDate((number * 10) * 86400) AS d1,
    toDate(number * 86400) AS d2,
    'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
    d1 WITH FILL STEP INTERVAL 1 DAY,
    d2 WITH FILL;
```

```response title="Response" theme={null}
┌─────────d1─┬─────────d2─┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-12 │ 1970-01-01 │          │
│ 1970-01-13 │ 1970-01-01 │          │
│ 1970-01-14 │ 1970-01-01 │          │
│ 1970-01-15 │ 1970-01-01 │          │
│ 1970-01-16 │ 1970-01-01 │          │
│ 1970-01-17 │ 1970-01-01 │          │
│ 1970-01-18 │ 1970-01-01 │          │
│ 1970-01-19 │ 1970-01-01 │          │
│ 1970-01-20 │ 1970-01-01 │          │
│ 1970-01-21 │ 1970-01-01 │          │
│ 1970-01-22 │ 1970-01-01 │          │
│ 1970-01-23 │ 1970-01-01 │          │
│ 1970-01-24 │ 1970-01-01 │          │
│ 1970-01-25 │ 1970-01-01 │          │
│ 1970-01-26 │ 1970-01-01 │          │
│ 1970-01-27 │ 1970-01-01 │          │
│ 1970-01-28 │ 1970-01-01 │          │
│ 1970-01-29 │ 1970-01-01 │          │
│ 1970-01-30 │ 1970-01-01 │          │
│ 1970-01-31 │ 1970-01-01 │          │
│ 1970-02-01 │ 1970-01-01 │          │
│ 1970-02-02 │ 1970-01-01 │          │
│ 1970-02-03 │ 1970-01-01 │          │
│ 1970-02-04 │ 1970-01-01 │          │
│ 1970-02-05 │ 1970-01-01 │          │
│ 1970-02-06 │ 1970-01-01 │          │
│ 1970-02-07 │ 1970-01-01 │          │
│ 1970-02-08 │ 1970-01-01 │          │
│ 1970-02-09 │ 1970-01-01 │          │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-11 │ 1970-01-01 │          │
│ 1970-02-12 │ 1970-01-01 │          │
│ 1970-02-13 │ 1970-01-01 │          │
│ 1970-02-14 │ 1970-01-01 │          │
│ 1970-02-15 │ 1970-01-01 │          │
│ 1970-02-16 │ 1970-01-01 │          │
│ 1970-02-17 │ 1970-01-01 │          │
│ 1970-02-18 │ 1970-01-01 │          │
│ 1970-02-19 │ 1970-01-01 │          │
│ 1970-02-20 │ 1970-01-01 │          │
│ 1970-02-21 │ 1970-01-01 │          │
│ 1970-02-22 │ 1970-01-01 │          │
│ 1970-02-23 │ 1970-01-01 │          │
│ 1970-02-24 │ 1970-01-01 │          │
│ 1970-02-25 │ 1970-01-01 │          │
│ 1970-02-26 │ 1970-01-01 │          │
│ 1970-02-27 │ 1970-01-01 │          │
│ 1970-02-28 │ 1970-01-01 │          │
│ 1970-03-01 │ 1970-01-01 │          │
│ 1970-03-02 │ 1970-01-01 │          │
│ 1970-03-03 │ 1970-01-01 │          │
│ 1970-03-04 │ 1970-01-01 │          │
│ 1970-03-05 │ 1970-01-01 │          │
│ 1970-03-06 │ 1970-01-01 │          │
│ 1970-03-07 │ 1970-01-01 │          │
│ 1970-03-08 │ 1970-01-01 │          │
│ 1970-03-09 │ 1970-01-01 │          │
│ 1970-03-10 │ 1970-01-01 │          │
│ 1970-03-11 │ 1970-01-01 │          │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
```

`STALENESS`를 사용하지 않는 쿼리 예시:

```sql title="Query" theme={null}
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL;
```

```text title="Response" theme={null}
    ┌─key─┬─value─┬─source───┐
 1. │   0 │     0 │ original │
 2. │   1 │     0 │          │
 3. │   2 │     0 │          │
 4. │   3 │     0 │          │
 5. │   4 │     0 │          │
 6. │   5 │    25 │ original │
 7. │   6 │     0 │          │
 8. │   7 │     0 │          │
 9. │   8 │     0 │          │
10. │   9 │     0 │          │
11. │  10 │    50 │ original │
12. │  11 │     0 │          │
13. │  12 │     0 │          │
14. │  13 │     0 │          │
15. │  14 │     0 │          │
16. │  15 │    75 │ original │
    └─────┴───────┴──────────┘
```

`STALENESS 3`를 적용한 후 동일한 쿼리:

```sql title="Query" theme={null}
SELECT number AS key, 5 * number value, 'original' AS source
FROM numbers(16) WHERE key % 5 == 0
ORDER BY key WITH FILL STALENESS 3;
```

```text title="Response" theme={null}
    ┌─key─┬─value─┬─source───┐
 1. │   0 │     0 │ original │
 2. │   1 │     0 │          │
 3. │   2 │     0 │          │
 4. │   5 │    25 │ original │
 5. │   6 │     0 │          │
 6. │   7 │     0 │          │
 7. │  10 │    50 │ original │
 8. │  11 │     0 │          │
 9. │  12 │     0 │          │
10. │  15 │    75 │ original │
11. │  16 │     0 │          │
12. │  17 │     0 │          │
    └─────┴───────┴──────────┘
```

`INTERPOLATE`가 없는 쿼리 예시:

```sql title="Query" theme={null}
SELECT n, source, inter FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5;
```

```text title="Response" theme={null}
┌───n─┬─source───┬─inter─┐
│   0 │          │     0 │
│ 0.5 │          │     0 │
│   1 │ original │     1 │
│ 1.5 │          │     0 │
│   2 │          │     0 │
│ 2.5 │          │     0 │
│   3 │          │     0 │
│ 3.5 │          │     0 │
│   4 │ original │     4 │
│ 4.5 │          │     0 │
│   5 │          │     0 │
│ 5.5 │          │     0 │
│   7 │ original │     7 │
└─────┴──────────┴───────┘
```

`INTERPOLATE`를 적용한 동일한 쿼리:

```sql title="Query" theme={null}
SELECT n, source, inter FROM (
   SELECT toFloat32(number % 10) AS n, 'original' AS source, number AS inter
   FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 INTERPOLATE (inter AS inter + 1);
```

```text title="Response" theme={null}
┌───n─┬─source───┬─inter─┐
│   0 │          │     0 │
│ 0.5 │          │     0 │
│   1 │ original │     1 │
│ 1.5 │          │     2 │
│   2 │          │     3 │
│ 2.5 │          │     4 │
│   3 │          │     5 │
│ 3.5 │          │     6 │
│   4 │ original │     4 │
│ 4.5 │          │     5 │
│   5 │          │     6 │
│ 5.5 │          │     7 │
│   7 │ original │     7 │
└─────┴──────────┴───────┘
```

<div id="filling-grouped-by-sorting-prefix">
  ## 정렬 접두사별 그룹화된 데이터 채우기
</div>

특정 컬럼에서 같은 값을 가진 행을 서로 독립적으로 채우는 기능이 유용할 수 있습니다. 대표적인 예로 시계열(time series)에서 누락된 값을 채우는 경우가 있습니다.
다음과 같은 시계열 테이블이 있다고 가정합니다:

```sql theme={null}
CREATE TABLE timeseries
(
    `sensor_id` UInt64,
    `timestamp` DateTime64(3, 'UTC'),
    `value` Float64
)
ENGINE = Memory;

SELECT * FROM timeseries;

┌─sensor_id─┬───────────────timestamp─┬─value─┐
│       234 │ 2021-12-01 00:00:03.000 │     3 │
│       432 │ 2021-12-01 00:00:01.000 │     1 │
│       234 │ 2021-12-01 00:00:07.000 │     7 │
│       432 │ 2021-12-01 00:00:05.000 │     5 │
└───────────┴─────────────────────────┴───────┘
```

그리고 각 센서별로 누락된 값을 1초 인터벌로 독립적으로 채우려고 합니다.
이를 위해 `sensor_id` 컬럼을 채우기를 적용할 `timestamp` 컬럼의 정렬 접두사로 사용합니다:

```sql theme={null}
SELECT *
FROM timeseries
ORDER BY
    sensor_id,
    timestamp WITH FILL
INTERPOLATE ( value AS 9999 )

┌─sensor_id─┬───────────────timestamp─┬─value─┐
│       234 │ 2021-12-01 00:00:03.000 │     3 │
│       234 │ 2021-12-01 00:00:04.000 │  9999 │
│       234 │ 2021-12-01 00:00:05.000 │  9999 │
│       234 │ 2021-12-01 00:00:06.000 │  9999 │
│       234 │ 2021-12-01 00:00:07.000 │     7 │
│       432 │ 2021-12-01 00:00:01.000 │     1 │
│       432 │ 2021-12-01 00:00:02.000 │  9999 │
│       432 │ 2021-12-01 00:00:03.000 │  9999 │
│       432 │ 2021-12-01 00:00:04.000 │  9999 │
│       432 │ 2021-12-01 00:00:05.000 │     5 │
└───────────┴─────────────────────────┴───────┘
```

여기서는 채워진 행이 더 잘 눈에 띄도록 `value` 컬럼을 `9999`로 보간했습니다.
이 동작은 `use_with_fill_by_sorting_prefix` 설정으로 제어되며, 기본적으로 활성화되어 있습니다.

<div id="related-content">
  ## 관련 콘텐츠
</div>

* 블로그: [ClickHouse에서 시계열 데이터 다루기](https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse)
