測試環境為 CentOS 8 x86_64
使用關聯式資料庫( RDBMS : Relational Database Management System )的 MariaDB 也可以儲存與查詢 NoSQL ( Not Only SQL : 使用非關聯式資料庫的資料庫,資料儲存不需要固定的欄位 ) 的 JSON ( JavaScript Object Notation )資料格式.
要怎麼合併 JSON 資料,可以透過 JSON_MERGE 或是 JSON_MERGE_PRESERVE (新版建議) 函數.
JSON_MERGE(json_doc, json_doc[, json_doc] ...)
[root@localhost ~]# mysql -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 10 Server version: 10.3.17-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- 合併相同 Key (Duplicate Keys)
MariaDB [testdb]> SELECT JSON_MERGE('{ "Name":"Alan" }', '{ "Name":"Cherry"}') Result; +------------------------------+ | Result | +------------------------------+ | {"Name": ["Alan", "Cherry"]} | +------------------------------+ 1 row in set (0.000 sec)
- 陣列 (Arrays)
MariaDB [testdb]> SELECT JSON_MERGE('{ "Name":["Alan","Apple","Cherry"] }', '{ "Name":"Cherry"}') Result; +-------------------------------------------------+ | Result | +-------------------------------------------------+ | {"Name": ["Alan", "Apple", "Cherry", "Cherry"]} | +-------------------------------------------------+ 1 row in set (0.000 sec)
從 SELECT 出來的 JSON 資料,可以透過 JSON_MERGE 函數來合併嗎? 下面來試試看.
MariaDB [(none)]> CREATE DATABASE testdb; Query OK, 1 row affected (0.001 sec) MariaDB [(none)]> USE testdb; Database changed
定義包含 json 欄位 (notebook) 的資料表 (json_tb).
SQL 語法:
CREATE TABLE project ( ID int(10) unsigned NOT NULL AUTO_INCREMENT, Name VARCHAR(200), Member JSON, PRIMARY KEY (ID) , CHECK (JSON_VALID(Member)) );
執行結果.
MariaDB [testdb]> CREATE TABLE project ( -> ID int(10) unsigned NOT NULL AUTO_INCREMENT, -> Name VARCHAR(200), -> Member JSON, PRIMARY KEY (ID) , CHECK (JSON_VALID(Member)) -> ); Query OK, 0 rows affected (0.008 sec)
建立兩筆資料 Project A 與 B .
依據 JSON 格式簡單定義了 Project 的成員資料(成員為非固定數量,很適合使用 JSON 格式來儲存).
{ "Name":["Alan","Joy","Art","Jimmy","Orion","Katrina"] } { "Name":["Cherry","Mark","Jerry","Rick"] }
MariaDB [testdb]> INSERT INTO project (Name,Member) VALUES ('Project A','{"Name":["Alan","Joy","Art","Jimmy","Orion","Katrina"]}') ; Query OK, 1 row affected (0.002 sec) MariaDB [testdb]> INSERT INTO project (Name,Member) VALUES ('Project B','{"Name":["Cherry","Mark","Jerry","Rick"]}') ; Query OK, 1 row affected (0.001 sec) MariaDB [testdb]> SELECT * FROM project; +----+-----------+---------------------------------------------------------+ | ID | Name | Member | +----+-----------+---------------------------------------------------------+ | 1 | Project A | {"Name":["Alan","Joy","Art","Jimmy","Orion","Katrina"]} | | 2 | Project B | {"Name":["Cherry","Mark","Jerry","Rick"]} | +----+-----------+---------------------------------------------------------+ 2 rows in set (0.001 sec)
- JSON_MERGE
來試試看 JSON_MERGE 資料來自 SELECT ,結果居然不行.MariaDB [testdb]> SELECT JSON_MERGE(Member) FROM project; ERROR 1582 (42000): Incorrect parameter count in the call to native function 'JSON_MERGE'
- CONCAT + GROUP_CONCAT
網路有提供一些其他方式 – https://dba.stackexchange.com/questions/153000/mysql-5-7-json-merge-combine-with-group-concat 但還要依據你的 JSON 格式再去調整 SQL 語法才能達成.SQL 語法
SELECT CONCAT('{', GROUP_CONCAT(SUBSTRING(Member, 2, length(Member) - 2)), '}') Member_Name FROM project WHERE Member != JSON_OBJECT();
執行結果
MariaDB [testdb]> SELECT CONCAT('{' , GROUP_CONCAT(SUBSTRING(Member, 2, length(Member) - 2)) , '}') Member_Name FROM project WHERE Member != JSON_OBJECT(); +-------------------------------------------------------------------------------------------------+ | Member_Name | +-------------------------------------------------------------------------------------------------+ | {"Name":["Alan","Joy","Art","Jimmy","Orion","Katrina"],"Name":["Cherry","Mark","Jerry","Rick"]} | +-------------------------------------------------------------------------------------------------+ 1 row in set (0.001 sec)
可以看到就單純把兩個 JSON 資料合在一起而已.
- Prepared Statement
更多關於使用 Prepared Statement 請參考 – https://benjr.tw/102000MariaDB [testdb]> SET @sql = NULL; Query OK, 0 rows affected (0.001 sec) MariaDB [testdb]> SELECT GROUP_CONCAT(CONCAT('\'',Member,'\'')) INTO @sql FROM project; Query OK, 1 row affected (0.002 sec) MariaDB [testdb]> SET @sql = CONCAT('SELECT JSON_MERGE(', @sql, ')'); Query OK, 0 rows affected (0.000 sec) MariaDB [testdb]> SELECT @sql; +--------------------------------------------------------------------------------------------------------------------------+ | @sql | +--------------------------------------------------------------------------------------------------------------------------+ | SELECT JSON_MERGE('{"Name":["Alan","Joy","Art","Jimmy","Orion","Katrina"]}','{"Name":["Cherry","Mark","Jerry","Rick"]}') | +--------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.000 sec) MariaDB [testdb]> MariaDB [testdb]> PREPARE stmt FROM @sql; Query OK, 0 rows affected (0.000 sec) Statement prepared
的確達到所需的效果.
MariaDB [testdb]> EXECUTE stmt; +-------------------------------------------------------------------------------------------------------------------+ | JSON_MERGE('{"Name":["Alan","Joy","Art","Jimmy","Orion","Katrina"]}','{"Name":["Cherry","Mark","Jerry","Rick"]}') | +-------------------------------------------------------------------------------------------------------------------+ | {"Name": ["Alan", "Joy", "Art", "Jimmy", "Orion", "Katrina", "Cherry", "Mark", "Jerry", "Rick"]} | +-------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.000 sec) MariaDB [testdb]> DEALLOCATE PREPARE stmt; Query OK, 0 rows affected (0.000 sec)
沒有解決問題,試試搜尋本站其他內容