全部產品
Search
文件中心

AnalyticDB:JSON函數

更新時間:Sep 27, 2025

本文介紹AnalyticDB for MySQL叢集支援的JSON函數。

  • JSON_ARRAY_CONTAINS:判斷JSON中是否包含value指定的值。

  • JSON_ARRAY_LENGTH:返回JSON數組的長度。

  • JSON_CONTAINS(3.1.5.0及以上版本):判斷指定Path中是否包含candidate的值;若未指定Path,則判斷Target中是否包含candidate指定的值。

  • JSON_CONTAINS_PATH(3.1.5.0及以上版本):判斷JSON中是否包含Path列表中的路徑。

  • JSON_EXTRACT:從JSON中返回json_path指定的值。

  • JSON_KEYS:若指定了json_path,表示擷取JSON在指定路徑下的所有鍵。若未指定json_path,表示擷取根路徑(即json_path='$')下的所有鍵。

  • JSON_OVERLAPS(3.1.10.6及以上版本):從指定JSON中返回包含candidate1candidate2candidate3等任意一個元素的值。

  • JSON_REMOVE(3.1.10.0及以上版本):從json中移除json_path指定的元素,並返回一個新的字串。您可以通過array[json_path,json_path,...]指定移除多個元素。

  • JSON_SIZE:從JSON中返回json_path指定JSON對象或JSON數組的大小。

  • JSON_SET(3.2.2.8及以上版本):在json中插入或更新指定json_path的資料並返回更新後的json

  • JSON_UNQUOTE(3.1.5.0及以上版本):去除json_value的雙引號並將json_value中的部分轉義符進行轉義後,返回處理結果。

JSON_ARRAY_CONTAINS

json_array_contains(json, value)
  • 命令說明:判斷JSON數組中是否包含value指定的值。

  • 輸入實值型別:value可以是數值、字串類型或BOOLEAN類型。

  • 傳回值類型:BOOLEAN。

  • 樣本:

    • 判斷JSON數組 [1, 2, 3]中是否包含值為2的元素,語句如下:

      SELECT json_array_contains('[1, 2, 3]', 2);

      返回結果如下:

      +-------------------------------------+
      | json_array_contains('[1, 2, 3]', 2) |
      +-------------------------------------+
      |                1                    |
      +-------------------------------------+

JSON_ARRAY_LENGTH

json_array_length(json)
  • 命令說明:返回JSON數組的長度。

  • 輸入實值型別:字串類型或JSON類型。

  • 傳回值類型:BIGINT。

  • 樣本:

    • 返回JSON數組[1, 2, 3]的長度,語句如下:

      SELECT json_array_length('[1, 2, 3]');

      返回結果如下:

      +--------------------------------+
      | json_array_length('[1, 2, 3]') |
      +--------------------------------+
      |                 3              |
      +--------------------------------+

JSON_CONTAINS

JSON_CONTAINS函數用於判斷指定JSON中是否包含特定內容,您可以在查詢資料時使用JSON Array索引,避免掃描全表資料或對整個JSON文檔進行解析,提升資料查詢效率。

未使用JSON索引

重要

僅3.1.5.0及以上核心版本的叢集支援該文法。

雲原生資料倉儲AnalyticDB MySQL控制台集群資訊頁面的配寘資訊地區,查看和升級核心版本

json_contains(target, candidate[, json_path])
  • 命令說明:

    • 若指定了json_path,則判斷指定Path中是否包含candidate的值。包含返回1,不包含返回0。

    • 若未指定json_path,則判斷Target中是否包含candidate指定的值。包含返回1,不包含返回0。

    規則如下:

    • targetcandidate均為PRIMITIVE類型(即NUMBER,BOOLEAN,STRING,NULL),當二者相等時,視為Target包含Candidate。

    • targetcandidate均為JSON數組,當Candidate的所有元素均包含於Target的某個元素中時,視為Target包含Candidate。

    • target為ARRAY類型且candidate為非ARRAY類型,當Candidate包含於Target的某個元素中時,視為Target包含Candidate。

    • targetcandidate均為JSON對象,當Candidate中的每個Key都包含於Target的Key中,且Candidate的Key對應的Value包含於Target中該Key對應的Value時,視為Target包含Candidate。

  • 輸入實值型別:targetcandidate為JSON類型,json_path為JSONPATH類型。

  • 傳回值類型:BOOLEAN。

  • 樣本:

    • 判斷$.a的路徑下是否包含值1,語句如下:

      SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '1', '$.a') as result;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      1 |
      +--------+
    • 判斷$.b的路徑下是否包含值1,語句如下:

      SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '1', '$.b') as result;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      0 |
      +--------+
    • 判斷{"d": 4}是否包含在Target中,語句如下:

      SELECT json_contains(json '{"a": 1, "b": 2, "c": {"d": 4}}', json '{"d": 4}') as result;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      0 |
      +--------+

使用JSON Array索引

重要
  • 僅3.1.10.6及以上核心版本的叢集支援該文法。

  • 指定的JSON列需建立JSON Array索引。詳情請參見建立JSON Array索引

  • 您可以在SQL查詢語句前增加EXPLAIN,查看SQL的執行計畫,若執行計畫中無ScanFilterProject運算元,則表明該查詢成功利用JSON Array索引,反之,則未利用JSON Array索引。

json_contains(json_path, cast('[candidate1,candidate2,candidate3]' as json)) 
  • 命令說明:判斷指定JSON中是否同時包含candidate1candidate2candidate3等元素。

  • 輸入實值型別:candidate1,candidate2,candidate3,......為數實值型別或字串類型,且多個值的類型需相同。

  • 傳回值類型:VARCHAR。

  • 樣本:

    • 判斷指定JSON列vj中是否包含CP-018673CP-018671

      SELECT  json_contains(vj, cast('["CP-018673","CP-018671"]' AS json)) FROM json_test;

      返回結果如下:

      +------------------------------------------------------------+
      |json_contains(vj, cast('["CP-018673","CP-018671"]' AS json))|                                                                    |
      +------------------------------------------------------------+
      |                    0                                       |
      +------------------------------------------------------------+
      |                    0                                       |
      +------------------------------------------------------------+
      |                    1                                       |
      +------------------------------------------------------------+
      |                    0                                       |
      +------------------------------------------------------------+
      |                    0                                       |
      +------------------------------------------------------------+
    • 判斷指定JSON列vj中是否包含CP-01867312

      SELECT json_contains(vj, cast('["CP-018673",1,2]' AS json)) FROM json_test;

      返回結果如下:

      +------------------------------------------------------------+
      |json_contains(vj, cast('["CP-018673","CP-018671"]' AS json))|                                                                    |
      +------------------------------------------------------------+
      |                    0                                       |
      +------------------------------------------------------------+
      |                    1                                       |
      +------------------------------------------------------------+
      |                    1                                       |
      +------------------------------------------------------------+
      |                    0                                       |
      +------------------------------------------------------------+
      |                    1                                       |
      +------------------------------------------------------------+

JSON_CONTAINS_PATH

json_contains_path(json, one_or_all, json_path[, json_path,...])
重要

僅3.1.5.0及以上核心版本的叢集支援使用該函數。

雲原生資料倉儲AnalyticDB MySQL控制台集群資訊頁面的配寘資訊地區,查看和升級核心版本

  • 命令說明:判斷JSON中是否包含Path對應的值。

    • one_or_all'one',JSON中包含所有Path中的其中之一時,返回1,否則返回0。

    • one_or_all'all',JSON中包含所有Path路徑時,返回1,否則返回0。

  • 輸入實值型別:json為JSON類型,one_or_all為VARCHAR類型(為'one'或者'all',不區分大小寫),json_path為Path路徑。

  • 傳回值類型:BOOLEAN。

  • 樣本:

    • 判斷JSON中是否包含$.a$.e至少一個的路徑,語句如下:

      SELECT json_contains_path(json '{"a": 1, "b": 2, "c": {"d": 4}}', 'one', '$.a', '$.e') AS RESULT;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      1 |
      +--------+
    • 判斷JSON中是否包含$.a$.e全部的路徑,語句如下:

      SELECT json_contains_path(json '{"a": 1, "b": 2, "c": {"d": 4}}', 'all', '$.a', '$.e') AS RESULT;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      0 |
      +--------+

JSON_EXTRACT

重要
  • JSON_EXTRACT函數的傳回值,同JSON類型的列一樣,均不支援ORDER BY

  • JSON_EXTRACT函數與JSON_UNQUOTE函數連用時,需要先使用CAST AS VARCHAR將JSON_EXTRACT函數的傳回值轉換為VARCHAR類型才能作為JSON_UNQUOTE函數的入參。

json_extract(json, json_path)
  • 命令說明:從JSON中返回json_path指定的值。若json中的Key存在特殊字元(例如:$.等),json_path的格式需為'$["Key"]'

    例如,Key為$data,json_path需填寫為'$["$data"]'

  • 輸入實值型別:字串類型或JSON類型。

  • 傳回值類型:JSON。

  • 樣本:

    • 返回數組[10, 20, [30, 40]]中路徑為$[0]的值,語句如下:

      SELECT json_extract('[10, 20, [30, 40]]', '$[0]');

      返回結果如下:

      +-------------------------------------------+
      | json_extract('[10, 20, [30, 40]]', '$[0]') |
      +-------------------------------------------+
      |                     10                    |
      +-------------------------------------------+
    • 返回{"id":"1","$date":"12345"}中路徑為$date的值,語句如下:

      SELECT JSON_EXTRACT('{"id":"1","$date":"12345"}', '$["$date"]');

      返回結果如下:

      +---------------------------------------------------------+
      |JSON_EXTRACT('{"id":"1","$date":"12345"}', '$["$date"]') |
      +---------------------------------------------------------+
      |                       "12345"                           |
      +---------------------------------------------------------+

JSON_KEYS

json_keys(json[, json_path])
  • 命令說明

    • 若指定了json_path,表示擷取JSON在指定路徑下的所有鍵。

    • 若未指定json_path,表示擷取根路徑(即json_path='$')下的所有鍵。

  • 輸入實值型別:僅支援輸入JSON類型的參數。

    您可以通過如下方式構造JSON資料:

    • 直接使用JSON資料。例如json '{"a": 1, "b": {"c": 30}}'

    • 通過CAST函數將字串顯式轉換為JSON資料。例如CAST('{"a": 1, "b": {"c": 30}}' AS json)

  • 傳回值類型:JSON ARRAY。

  • 樣本:

    • 返回$.b路徑下的所有鍵,語句如下:

      SELECT json_keys(CAST('{"a": 1, "b": {"c": 30}}' AS json),'$.b');

      返回結果如下:

      +-----------------------------------------------------------+
      | json_keys(CAST('{"a": 1, "b": {"c": 30}}' AS json),'$.b') |
      +-----------------------------------------------------------+
      |                           ["c"]                           |
      +-----------------------------------------------------------+
    • 返回根路徑下的所有鍵,語句如下:

      SELECT JSON_KEYS(json '{"a": 1, "b": {"c": 30}}');

      返回結果如下:

      +--------------------------------------------+
      | JSON_KEYS(json '{"a": 1, "b": {"c": 30}}') |
      +--------------------------------------------+
      |             ["a","b"]                      |
      +--------------------------------------------+

JSON_OVERLAPS

重要
  • 僅3.1.10.6及以上核心版本的叢集支援該文法。

  • 指定的JSON列需建立JSON Array索引。詳情請參見建立JSON Array索引

  • 您可以在SQL查詢語句前增加EXPLAIN,查看SQL的執行計畫,若執行計畫中無ScanFilterProject運算元,則表明該查詢成功利用JSON Array索引,反之,則未利用JSON Array索引。

json_overlaps(json, cast('[candidate1,candidate2,candidate]' as json)) 
  • 命令說明:返回指定JSON中包含candidate1candidate2candidate3等任意一個元素的資料。

  • 輸入實值型別:candidate1,candidate2,candidate3,...為數實值型別或字串類型,且多個值的類型需相同。

  • 傳回值類型:VARCHAR。

  • 樣本:

    • 返回指定JSON列vj中包含CP-018673的資料。

      SELECT * FROM json_test WHERE json_overlaps(vj, cast('["CP-018673"]' AS json));

      返回結果如下:

      +-----+----------------------------------------------------------------------------+
      |  id |   vj                                                                       |
      +-----+----------------------------------------------------------------------------+
      |  2  | ["CP-018673", 1, false]                                                    |
      +-----+----------------------------------------------------------------------------+
      |  3  | ["CP-018673", 1, false, {"a": 1}]                                          |
      +-----+----------------------------------------------------------------------------+
      |  5  | ["CP-018673","CP-018671","CP-018672","CP-018670","CP-018669","CP-018668"]  |
      +-----+----------------------------------------------------------------------------+
    • 返回指定JSON列vj中包含123任意一個元素的資料。

      SELECT * FROM json_test WHERE json_overlaps(vj, cast('[1,2,3]' AS json))

      返回結果如下:

      +-----+-------------------------------------+
      |  id |                 vj                  |
      +-----+-------------------------------------+
      |  1  | [1,2,3]                             |
      +-----+-------------------------------------+
      |  2  | ["CP-018673", 1, false]             |
      +-----+-------------------------------------+
      |  3  | ["CP-018673", 1, false, {"a": 1}]   |
      +-----+-------------------------------------+

JSON_REMOVE

重要

僅3.1.10.0及以上核心版本的叢集支援使用JSON_REMOVE函數。

雲原生資料倉儲AnalyticDB MySQL控制台集群資訊頁面的配寘資訊地區,查看和升級核心版本

json_remove(json,json_path)
json_remove(json,array[json_path,json_path,...])
  • 命令說明:從json中移除json_path指定的元素,並返回一個新的字串。您可以通過array[json_path,json_path,...]指定移除多個元素。

  • 輸入實值型別:json為JSON格式的VARCHAR類型。json_path為JSON格式的VARCHAR類型。

  • 傳回值類型:VARCHAR。

  • 樣本

    • 移除路徑為$.glossary.GlossDiv的部分,並返回修改後的字串,語句如下:

        SELECT json_remove(
        '{
            "glossary": {
                "title": "example glossary",
                "GlossDiv": {
                    "title": "S",
                    "GlossList": {
                        "GlossEntry": {
                            "ID": "SGML",
                            "SortAs": "SGML",
                            "GlossTerm": "Standard Generalized Markup Language",
                            "Acronym": "SGML",
                            "Abbrev": "ISO 8879:1986",
                            "GlossDef": {
                                "para": "A meta-markup language, used to create markup languages such as DocBook.",
                                "GlossSeeAlso": ["GML", "XML"]
                            },
                            "GlossSee": "markup"
                        }
                    }
                }
            }
        }'
        , '$.glossary.GlossDiv') a;

      返回結果如下:

      {"glossary":{"title":"example glossary"}}
    • 移除路徑為$.glossary.title$.glossary.GlossDiv.title的部分,並返回修改後的字串,語句如下:

      SELECT json_remove(
        '{
            "glossary": {
                "title": "example glossary",
                "GlossDiv": {
                    "title": "S",
                    "GlossList": {
                        "GlossEntry": {
                            "ID": "SGML",
                            "SortAs": "SGML",
                            "GlossTerm": "Standard Generalized Markup Language",
                            "Acronym": "SGML",
                            "Abbrev": "ISO 8879:1986",
                            "GlossDef": {
                                "para": "A meta-markup language, used to create markup languages such as DocBook.",
                                "GlossSeeAlso": ["GML", "XML"]
                            },
                            "GlossSee": "markup"
                        }
                    }
                }
            }
        }'
        , array['$.glossary.title', '$.glossary.GlossDiv.title']) a;

      返回結果如下:

      {"glossary":{"GlossDiv":{"GlossList":{"GlossEntry":{"GlossTerm":"Standard Generalized Markup Language","GlossSee":"markup","SortAs":"SGML","GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"ID":"SGML","Acronym":"SGML","Abbrev":"ISO 8879:1986"}}}}}

JSON_SIZE

json_size(json, json_path)
  • 命令說明:從JSON中返回json_path指定JSON對象或JSON數組的大小。

    說明

    json_path指向的不是JSON對象或者JSON數組時,返回0。

  • 輸入實值型別:字串類型或JSON類型。

  • 傳回值類型:BIGINT。

  • 樣本:

    • json_path指向的是JSON對象,語句如下:

      SELECT json_size('{"x":{"a":1, "b": 2}}', '$.x') as result;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      2 |
      +--------+
    • json_path指向的不是JSON對象或者JSON數組,語句如下:

      SELECT json_size('{"x": {"a": 1, "b": 2}}', '$.x.a') as result;

      返回結果如下:

      +--------+
      | result |
      +--------+
      |      0 |
      +--------+

JSON_SET

重要

僅3.2.2.8及以上核心版本的叢集支援使用JSON_SET函數。

雲原生資料倉儲AnalyticDB MySQL控制台集群資訊頁面的配寘資訊地區,查看和升級核心版本

json_set(json, json_path, value[, json_path, value] ...)
  • 命令說明:在json中插入或更新指定json_path的資料並返回更新後的json

    • 如果jsonjson_path為null,則返回null。

    • 如果json不符合JSON格式規範,或者任一json_path不是一個有效路徑運算式,則會拋出異常。

    • 如果指定的json_path存在,則會使用value覆蓋原有的資料。

    • 如果指定的json_pathjson中不存在:

      • json_path指向的是JSON對象,value會作為新資料添加到json_path指定的位置中。

      • json_path指向的是JSON數組,先判斷指定json_path位置前是否有資料,若沒有,則補充null之後再插入value的資料。反之,則直接插入value的資料。

      • 其他情況則會拋出異常。

  • 輸入實值型別:

    • json:VARCHAR 或JSON。

    • json_path:VARCHAR。

    • value:BOOLEAN、TINYINT、SMALLINT、INT、BIGINT、FLOAT、DOUBLE、DECIMAL、VARCHAR、VARBINARY、DATE、DATETIME、TIMESTAMP、TIME。

  • 傳回值類型:JSON。

  • 樣本:

    • json中插入資料,其中json_path為null。

      SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', null, '10');

      返回結果:

      +------------------------------------------------+
      | JSON_SET('{ "a": 1, "b": [2, 3]}', NULL, '10') |
      +------------------------------------------------+
      | null                                           |
      +------------------------------------------------+
    • json中插入資料,其中json_path不是一個有效路徑運算式。

      SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.b.c', '10');

      返回結果:

      Failed to execute json_set() for json_path: $.b.c
    • json中插入資料,其中json_path1已存在,json_path2不存在且指向的是JSON對象。

      SELECT JSON_SET('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]');

      返回結果:

      +-----------------------------------------------------------------------+
      | JSON_SET('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]') |
      +-----------------------------------------------------------------------+
      | {"a":10,"b":[2,3],"c":"[true, false]"}                                |
      +-----------------------------------------------------------------------+
    • json中插入資料,指定的json_path不存在,且指向的是JSON數組。

      SELECT JSON_SET('{ "a": 1, "b": [2, 3]}',  '$.b[4]', '[true, false]');

      返回結果:

      +----------------------------------------------------------------+
      | JSON_SET('{ "a": 1, "b": [2, 3]}',  '$.b[4]', '[true, false]') |
      +----------------------------------------------------------------+
      | {"a":1,"b":[2,3,null,null,"[true, false]"]}                    |
      +----------------------------------------------------------------+

JSON_UNQUOTE

json_unquote(json_value)
重要

僅3.1.5.0及以上核心版本的叢集支援使用該函數。

雲原生資料倉儲AnalyticDB MySQL控制台集群資訊頁面的配寘資訊地區,查看和升級核心版本

  • 命令說明:去除json_value的雙引號並將其中的部分轉義符進行轉義後,返回處理結果。

    AnalyticDB for MySQL不會判斷json_value的合法性,即無論json_value是否符合JSON文法都會按上述邏輯進行處理。

    支援的轉義符如下表。

    轉義前

    轉義後

    \"

    雙引號(")。

    \b

    退格鍵。

    \f

    換頁符。

    \n

    分行符號。

    \r

    斷行符號符。

    \t

    Tab鍵。

    \\

    反斜線(\)。

    \uXXXX

    UTF-8字元表示。

  • 輸入實值型別:VARCHAR。

  • 傳回值類型:VARCHAR。

  • 樣本:

    • 返回去除引號後的字串abc,語句如下:

      SELECT json_unquote('"abc"');

      返回結果如下:

      +-----------------------+
      | json_unquote('"abc"') |
      +-----------------------+
      |          abc          |
      +-----------------------+
    • 返回去除引號並解析後的字串,語句如下:

      SELECT json_unquote('"\\t\\u0032"');

      返回結果如下:

      +------------------------------+
      | json_unquote('"\\t\\u0032"') |
      +------------------------------+
      |               2              |
      +------------------------------+

附錄:JSON Path文法說明

使用方法

  • 使用$.keyName[.keyName]...訪問JSON對象中的指定鍵。

  • 使用$[nonNegativeInteger]訪問JSON數組中的第n個元素,n為非負整數。

  • 使用$.keyName[.keyName]...[nonNegativeInteger]訪問JSON對象中嵌套的JSON數組的第n個元素,n為非負整數。

注意事項

AnalyticDB for MySQL JSON Path文法不支援萬用字元***。即不支援以下寫法'$.*''$.hobbies[*]''$.address.**'以及'$.hobbies.**'

樣本

假設有以下JSON資料。

{
    "name": "Alice",
    "age": 25,
    "address": {
        "city": "Hangzhou",
        "zip": "10001"
    },
    "hobbies":["reading", "swimming", "cycling"]
}

樣本說明

正確樣本

錯誤樣本

訪問鍵name的值

$.name

name

訪問嵌套對象city鍵的值

$.address.city

$.address[0]

訪問JSON數組hobbies的第1個元素

$.hobbies[0]

$.hobbies.[0]

常見問題

如何解決使用JSON_OVERLAPS函數時,出現java.lang.NullPointerException報錯?

原因:使用ALTER語句建立JSON索引後,未執行BUILD操作,或BUILD操作尚未完成,此時JSON索引尚未生效,導致該報錯。

解決方案:

  • 若未執行BUILD操作:

    AnalyticDB for MySQL叢集會在滿足一定條件後自動觸發BUILD任務,您也可以手動觸發BUILD任務

  • 若已執行BUILD操作:

    您可以通過如下語句,查詢BUILD任務的狀態。若返回欄位status的值為FINISH,表示BUILD操作已完成。

    SELECT table_name, schema_name, status FROM INFORMATION_SCHEMA.KEPLER_META_BUILD_TASK ORDER BY create_time DESC LIMIT 10;

更多BUILD的資訊,請參見BUILD

相關文檔

  • JSON:瞭解JSON類型。

  • JSON索引:瞭解如何為JSON對象或JSON數組建立索引。