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

> Agrega valores JSON mediante la semántica de JSON Merge Patch, en la que prevalece la última escritura (last-write-wins).

# mergedJSONPatch

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

Introducido en: v26.8.0

Agrega valores JSON fusionándolos con una semántica en la que prevalece la última escritura, e implementa el comportamiento principal de fusión
de RFC 7396 JSON Merge Patch a nivel de ruta.

La función de agregación almacena el estado como tripletas (key, value, sorting\_key), donde cada clave (ruta JSON)
solo conserva el registro efectivo más reciente según la sorting\_key. Las escrituras de objetos se aplanan en
rutas descendientes en el caso de las rutas que el tipo `JSON` almacena como hojas escalares dinámicas. Las escrituras de ancestros que no son objetos
prevalecen sobre los descendientes en conflicto.

Cada ruta con tipo explícito (declarada con `JSON(a Map(...))`, `JSON(a Tuple(...))`,
`JSON(a Variant(...))`, `JSON(a Dynamic)`, etc.) se trata como un valor atómico: el valor completo de la ruta
se sustituye por el del patch más reciente en lugar de fusionarse en profundidad. Solo las rutas escalares sin tipo (dinámicas) siguen
la semántica de fusión profunda de la RFC 7396.

El sort\_key determina qué valor prevalece para cada ruta JSON. Se conserva la fila con el sort\_key
más alto. Si dos parches en conflicto tienen la misma clave de ordenación, el resultado depende del orden: prevalece el parche
que se procese en último lugar. No se debe confiar en `ORDER BY` para deshacer empates de forma determinista.

LIMITACIONES (heredadas de `ColumnObject`):

1. Eliminación de valores nulos: un patch `{"key": null}` no elimina la clave. `ColumnObject` descarta
   los miembros con valor nulo durante la inserción, por lo que la función no puede distinguir entre "clave ausente" y
   "clave con valor nulo".

2. Reemplazo con objeto vacío: un patch `{"a": {}}` no puede sustituir un valor escalar o array anterior
   en la ruta `a`. `ColumnObject` descarta silenciosamente las rutas cuyo valor es un objeto vacío `{}`,
   por lo que el patch más reciente no aporta nada y el valor anterior se mantiene.

3. Ausencia en rutas tipadas no Nullable: cuando una columna `JSON` declara una ruta tipada con un
   tipo no Nullable (p. ej., `JSON(a UInt32)`), una fila que omite `a` se almacena con el
   valor predeterminado del tipo (p. ej., `0`). La agregación no puede distinguir entre "ausente" y "escrito
   explícitamente con el valor predeterminado", por lo que un patch más reciente que omite `a` borra silenciosamente un valor
   anterior distinto de cero. Para evitarlo, declare las rutas tipadas como `Nullable`
   (p. ej., `JSON(a Nullable(UInt32))`). Un valor nulo en una ruta tipada Nullable se trata como
   "ruta ausente" y se omite correctamente.

4. Todas las rutas tipadas son atómicas: cada ruta tipada (`Map(K,V)`, `JSON`, `Dynamic`, `Tuple(…)`,
   `Variant(…)`, `Array(…)` o cualquier otro tipo declarado) se almacena como un único valor. La
   agregación reemplaza el valor completo de forma atómica, en lugar de fusionar su contenido en profundidad.
   Solo las rutas dinámicas (no tipadas, escalares) se fusionan en profundidad, ruta por ruta.

5. Ambigüedad por puntos en las claves: el tipo `JSON` representa `{"a":{"b":1}}` y `{"a.b":1}` con
   la misma ruta interna `a.b`. Por lo tanto, una misma fila puede exponer tanto `a` como `a.b` como
   elementos independientes del mismo nivel. Cuando un patch más reciente escribe solo `a`, la regla de conflicto
   entre ancestro y descendiente borra `a.b`; cuando escribe solo `a.b`, esa misma regla borra `a`. Para evitarlo,
   establezca `json_type_escape_dots_in_keys = 1`. Con este ajuste, los puntos literales de las claves JSON
   se representan mediante codificación porcentual (p. ej., `a.b` se convierte en `a%2Eb`), lo que los distingue de las rutas
   anidadas y elimina el falso conflicto.

**Sintaxis**

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

**Argumentos**

* `json` — Columna JSON que se va a agregar. [`JSON`](/es/reference/data-types/newjson)
* `sort_key` — Columna comparable que determina qué escritura prevalece para cada ruta. Se conserva la fila con el valor de sort\_key más alto.

**Valor devuelto**

Devuelve un único objeto JSON resultante de fusionar todos los objetos JSON de entrada. [`JSON`](/es/reference/data-types/newjson)

**Ejemplos**

**Uso básico con clave de ordenación**

```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}             │
└─────────────────────────────────┘
```
