跳到主要内容
最后于 更新

JSON_EXTRACT

描述​

从 JSON 类型的数据中提取 json_path 指定的字段。

语法​

JSON_EXTRACT (<json_object>, <path>[, <path2>, ...])

参数​

参数描述
<json_object>必需。JSON 值,或可转换为 JSON 的合法 JSON 字符串。
<path>必需。STRING 类型的 JSON 路径;数组遍历使用显式通配符。
<path2>, ...可选。其他 STRING 类型路径;匹配结果组合为 JSON 数组。

返回值​

任一参数为 NULL,或所有路径均没有匹配值时,返回 SQL NULL。

  • Nullable(JSON): 返回 <path> 指向的 JSON 元素,如果匹配了多个结果会以 JSON 数组的形式返回。

使用说明​

  • 如果 <json_object> 是 NULL,或者 <path> 是 NULL,返回 NULL。

  • 对于单个 <path> 参数的情况,如果 <path> 如果路径不存在,返回 NULL。

  • 对于多个 <path> 参数的情况,如果所有字段都不在 JSON 中,返回 NULL;否则跳过不存在的字段,将匹配到的元素组成 JSON 数组返回。

  • 如果 <path> 不是一个合法的路径,报错。

  • 如果 <path> 对应的值是字符串,返回的字符串会被双引号(")包围,如果要得到没有双引号的结果,请对结果使用函数 JSON_UNQUOTE 以去掉双引号。

  • <path> 的语法如下

    • $ 代表 json root
    • .k1 代表 json object 中 key 为k1的元素
      • 如果 key 列值包含 ".", <path> 中需要用双引号,例如 SELECT json_extract('{"k1.a":"abc","k2":300}', '$."k1.a"');
    • [i] 代表 json array 中下标为 i 的元素
      • 获取 json_array 的最后一个元素可以用$[last],倒数第二个元素可以用$[last-1],以此类推。
    • * 代表通配符,即 $.* 代表根对象的所有成员,$[*] 代表数组的所有元素。
    • ** 代表通配符,通常和 '′一起使用:′' 一起使用: '**' 代表所有的路径(以及多层的子路径,见下面的示例 9)。
  • 如果 <path> 存在通配符(*),匹配的结果会以数组形式返回。

  • <path> 不会在数组上自动广播。如果 <json_object> 是 JSON 数组,<path> 为 $.k,结果为 NULL —— $.k 只会遍历 object 的成员。要按下标访问元素,使用 $[i].k;要从数组的每个元素中提取字段,使用通配符语法 $[*].k,该语法自 Doris 4.0 起支持。

示例​

  1. 一般参数
    SELECT JSON_EXTRACT('{"k1":"v31","k2":300}', '$.k1');

```text
+-----------------------------------------------+
| JSON_EXTRACT('{"k1":"v31","k2":300}', '$.k1') |
+-----------------------------------------------+
| "v31" |
+-----------------------------------------------+
```
> 注意:返回的结果是`"v31"` 不是 `v31`。
2. NULL 参数
```sql
select JSON_EXTRACT(null, '$.k1');
```
```text
+----------------------------+
| JSON_EXTRACT(null, '$.k1') |
+----------------------------+
| NULL |
+----------------------------+
```
3. `<path>` 为 NULL
```sql
SELECT JSON_EXTRACT('{"k1":"v31","k2":300}', NULL);
```
```text
+---------------------------------------------+
| JSON_EXTRACT('{"k1":"v31","k2":300}', NULL) |
+---------------------------------------------+
| NULL |
+---------------------------------------------+
```
4. 多级路径
```sql
SELECT JSON_EXTRACT('{"k1":"v31","k2":{"sub_key": 1234.56}}', '$.k2.sub_key');
```
```text
+------------------------------------------------------------------------+
| JSON_EXTRACT('{"k1":"v31","k2":{"sub_key": 1234.56}}', '$.k2.sub_key') |
+------------------------------------------------------------------------+
| 1234.56 |
+------------------------------------------------------------------------+
```
5. 数组路径
```sql
SELECT JSON_EXTRACT(json_array("abc", 123, cast(now() as string)), '$[2]');
```
```text
+----------------------------------------------------------------------+
| JSON_EXTRACT(json_array("abc", 123, cast(now() as string)), '$.[2]') |
+----------------------------------------------------------------------+
| "2025-07-16 18:35:25" |
+----------------------------------------------------------------------+
```
6. 不存在的 path
```sql
SELECT JSON_EXTRACT('{"k1":"v31","k2":300}', '$.k3');
```
```text
+-----------------------------------------------+
| JSON_EXTRACT('{"k1":"v31","k2":300}', '$.k3') |
+-----------------------------------------------+
| NULL |
+-----------------------------------------------+
```
7. 多个路径参数
```sql
select JSON_EXTRACT('{"id": 123, "name": "doris"}', '$.name', '$.id', '$.not_exists');
```
```text
+--------------------------------------------------------------------------------+
| JSON_EXTRACT('{"id": 123, "name": "doris"}', '$.name', '$.id', '$.not_exists') |
+--------------------------------------------------------------------------------+
| ["doris",123] |
+--------------------------------------------------------------------------------+
```
> 即使只有一个匹配也会以数组形式返回
```sql
SELECT json_extract('{"id": 123, "name": "doris"}', '$.aaa', '$.name');
```
```text
+-----------------------------------------------------------------+
| json_extract('{"id": 123, "name": "doris"}', '$.aaa', '$.name') |
+-----------------------------------------------------------------+
| ["doris"] |
+-----------------------------------------------------------------+
```
```sql
> 如果所有路径都没有匹配则返回 NULL
select JSON_EXTRACT('{"id": 123, "name": "doris"}', '$.k1', '$.k2', '$.not_exists');
```
```text
+------------------------------------------------------------------------------+
| JSON_EXTRACT('{"id": 123, "name": "doris"}', '$.k1', '$.k2', '$.not_exists') |
+------------------------------------------------------------------------------+
| NULL |
+------------------------------------------------------------------------------+
```

8. 通配符路径
```sql
select json_extract('{"k": [1,2,3,4,5]}', '$.k[*]');
```
```text
+----------------------------------------------+
| json_extract('{"k": [1,2,3,4,5]}', '$.k[*]') |
+----------------------------------------------+
| [1,2,3,4,5] |
+----------------------------------------------+
```
```sql
select json_extract('{"k": [1,2,3,4,5], "k2": "abc", "k3": {"k4": "v4"}}', '$.*', '$.k3.k4');
```
```text
+---------------------------------------------------------------------------------------+
| json_extract('{"k": [1,2,3,4,5], "k2": "abc", "k3": {"k4": "v4"}}', '$.*', '$.k3.k4') |
+---------------------------------------------------------------------------------------+
| [[1,2,3,4,5],"abc",{"k4":"v4"},"v4"] |
+---------------------------------------------------------------------------------------+
```
9. '**' 作为通配符
```sql
select json_extract('{"k": 123, "b": {"k": ["ab", "cd"]}}', '$**.k');
```
```text
+---------------------------------------------------------------+
| json_extract('{"k": 123, "b": {"k": ["ab", "cd"]}}', '$**.k') |
+---------------------------------------------------------------+
| [123,["ab","cd"]] |
+---------------------------------------------------------------+
```
10. Value 是 NULL 的情况
```sql
select JSON_EXTRACT('{"id": 123, "name": null}', '$.name') v, JSON_EXTRACT('{"id": 123, "name": null}', '$.name') is null v2;
```
```text
+------+------+
| v | v2 |
+------+------+
| null | 0 |
+------+------+
```

11. 从 JSON 数组的每个元素中提取字段(Doris 4.0+)
```sql
select json_extract('[{"k":1},{"k":2},{"k":3}]', '$.k');
```
```text
+--------------------------------------------------+
| json_extract('[{"k":1},{"k":2},{"k":3}]', '$.k') |
+--------------------------------------------------+
| NULL |
+--------------------------------------------------+
```
> `$.k` 不会遍历数组,只会下钻到对象的成员。
```sql
select json_extract('[{"k":1},{"k":2},{"k":3}]', '$[*].k');
```
```text
+-----------------------------------------------------+
| json_extract('[{"k":1},{"k":2},{"k":3}]', '$[*].k') |
+-----------------------------------------------------+
| [1,2,3] |
+-----------------------------------------------------+
```
> 使用 `$[*].k` 从数组的每个元素提取字段。

### 提取数组中的同名字段(Doris 4.0 及后续版本)

使用 `$[*].k1` 显式遍历数组元素;`$.k1` 只访问对象成员,不会隐式遍历数组,因此下面的直接路径返回 SQL `NULL`。没有 `k1` 的数组元素会被忽略。
```sql
SELECT json_extract('[{"k1":"v1"},{"k2":"v2"},{"k1":"v3"},{"k1":"v4"}]', '$.k1') AS direct_path,
json_extract('[{"k1":"v1"},{"k2":"v2"},{"k1":"v3"},{"k1":"v4"}]', '$[*].k1') AS all_values;
+-------------+------------------+
| direct_path | all_values |
+-------------+------------------+
| NULL | ["v1","v3","v4"] |
+-------------+------------------+