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

> 마지막 쓰기 우선(last-write-wins) 방식의 JSON Merge Patch 의미 체계에 따라 JSON 값을 집계합니다.

# mergedJSONPatch

<h2 id="mergedJSONPatch">
  mergedJSONPatch
</h2>

도입 버전: v26.8.0

JSON 값을 마지막 쓰기 우선(last-write-wins) 의미 체계로 머지하여 집계하며, RFC 7396 JSON Merge Patch의 핵심 머지
동작을 경로 수준에서 구현합니다.

이 집계 함수는 상태를 (key, value, sorting\_key) 형태의 3개 항목 튜플로 저장하며, 각 key(JSON 경로)마다
sorting\_key를 기준으로 가장 최신의 유효한 레코드만 유지합니다. `JSON` 타입이 동적 스칼라 리프로 저장하는 경로에서는 객체 쓰기가
하위 경로로 평탄화됩니다. 상위 경로에 객체가 아닌 값을 쓰면
충돌하는 하위 경로는 가려집니다.

명시적으로 타입이 지정된 모든 경로(`JSON(a Map(...))`, `JSON(a Tuple(...))`,
`JSON(a Variant(...))`, `JSON(a Dynamic)` 등으로 선언된 경로)는 원자적(atomic) 값으로 처리됩니다. 즉, 경로 값 전체가
딥 머지되지 않고 더 최신 패치로 대체됩니다. 타입이 지정되지 않은(동적) 스칼라 경로만
RFC 7396 딥 머지 의미 체계를 따릅니다.

sort\_key는 각 JSON 경로에서 어떤 값이 우선할지 결정합니다. sort\_key가 가장 큰 행이
유지됩니다. 충돌하는 두 패치의 정렬 키가 같으면 결과는 처리 순서에 따라 달라지며, 나중에
처리된 패치가 우선합니다. 동률을 결정론적으로 해소하는 용도로 `ORDER BY`에 의존하지 마십시오.

제한 사항(`ColumnObject`에서 상속됨):

1. Null 삭제: 패치 `{"key": null}`은 키를 제거하지 않습니다. `ColumnObject`는 삽입 시 값이 null인
   멤버를 삭제하므로, 함수는 "키 없음"과
   "키가 null임"을 구분할 수 없습니다.

2. 빈 객체로의 대체: 패치 `{"a": {}}`로는 경로 `a`에 있는 이전 스칼라 값이나 배열을
   대체할 수 없습니다. `ColumnObject`는 값이 빈 객체 `{}`인 경로를 별도 알림 없이 삭제하므로,
   새 패치는 아무런 영향을 주지 못하고 이전 값이 그대로 유지됩니다.

3. 널 비허용(Non-Nullable) 타입이 지정된 경로의 부재: `JSON` 컬럼에서 널을 허용하지 않는 타입으로
   타입이 지정된 경로를 선언하면(예: `JSON(a UInt32)`), `a`가 생략된 행은 해당
   타입의 기본값(예: `0`)으로 저장됩니다. 집계 함수는 "부재"와 "기본값으로
   명시적으로 기록됨"을 구분할 수 없으므로, `a`를 생략한 새 패치가 0이 아닌 이전 값을
   별도 알림 없이 지워 버립니다. 이를 방지하려면 타입이 지정된 경로를 `Nullable`로 선언하십시오
   (예: `JSON(a Nullable(UInt32))`). 널 허용 타입이 지정된 경로의 null은
   "경로 없음"으로 처리되어 올바르게 건너뜁니다.

4. 타입이 지정된 경로는 모두 원자적으로 처리됨: 타입이 지정된 모든 경로(`Map(K,V)`, `JSON`, `Dynamic`, `Tuple(…)`,
   `Variant(…)`, `Array(…)` 또는 기타 선언된 타입)는 단일 값으로 저장됩니다. 집계 함수는
   내용을 깊은 머지(deep merge)하지 않고 값 전체를 원자적으로 대체합니다.
   동적(타입이 지정되지 않은 스칼라) 경로만 경로 단위로 깊은 머지됩니다.

5. 키에 포함된 점으로 인한 모호성: `JSON` 타입은 `{"a":{"b":1}}`과 `{"a.b":1}`을
   동일한 내부 경로 `a.b`로 표현합니다. 따라서 하나의 행에서 `a`와 `a.b`가 서로
   독립적인 피어로 함께 노출될 수 있습니다. 새 패치가 `a`만 기록하면 상위/하위 충돌
   규칙에 따라 `a.b`가 지워지고, `a.b`만 기록하면 같은 규칙에 따라 `a`가 지워집니다. 이를 방지하려면
   `json_type_escape_dots_in_keys = 1`로 설정하십시오. 이 설정을 사용하면 JSON 키에 포함된 리터럴 점이
   퍼센트 인코딩되어(예: `a.b`가 `a%2Eb`로 변환됨) 중첩 경로와 구분되므로
   잘못된 충돌이 발생하지 않습니다.

**구문**

```sql theme={null}
mergedJSONPatch(json, sort_key)
```

**인수**

* `json` — 집계할 JSON 컬럼입니다. [`JSON`](/ko/reference/data-types/newjson)
* `sort_key` — 각 경로마다 어떤 쓰기를 최종 반영할지 결정하는 비교 가능한 컬럼입니다. sort\_key 값이 가장 큰 행이 유지됩니다.

**반환 값**

입력된 모든 JSON 객체를 병합한 결과로 단일 JSON 객체를 반환합니다. [`JSON`](/ko/reference/data-types/newjson)

**예시**

**정렬 키를 사용한 기본 사용법**

```sql title=Query theme={null}
SELECT mergedJSONPatch(json, sort_key) FROM
(
    SELECT '{"a":1}'::JSON AS json, 1 AS sort_key
    UNION ALL
    SELECT '{"b":2}'::JSON, 2
    UNION ALL
    SELECT '{"a":3, "c":4}'::JSON, 3
);
```

```response title=Response theme={null}
┌─mergedJSONPatch(json, sort_key)─┐
│ {"a":3,"b":2,"c":4}             │
└─────────────────────────────────┘
```
