最后于 更新
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"');
- 如果 key 列值包含 ".",
[i]代表 json array 中下标为 i 的元素- 获取 json_array 的最后一个元素可以用
$[last],倒数第二个元素可以用$[last-1],以此类推。
- 获取 json_array 的最后一个元素可以用
*代表通配符,即$.*代表根对象的所有成员,$[*]代表数组的所有元素。**代表通配符,通常和 '**' 代表所有的路径(以及多层的子路径,见下面的示例 9)。
-
如果
<path>存在通配符(*),匹配的结果会以数组形式返回。 -
<path>不会在数组上自动广播。如果<json_object>是 JSON 数组,<path>为$.k,结果为 NULL ——$.k只会遍历 object 的成员。要按下标访问元素,使用$[i].k;要从数组的每个元素中提取字段,使用通配符语法$[*].k,该语法自 Doris 4.0 起支持。
示例
- 一般参数
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"] |
+-------------+------------------+