P粉8271215582023-08-28 13:36:44
確實,非規範化為 JSON 不是一個好主意,但有時您需要處理 JSON 數據,並且有一種方法可以將 JSON 數組提取到查詢中的行中。
技巧是對臨時或內聯索引表執行聯接,這為 JSON 陣列中的每個非空值提供一行。即,如果您有一個值為0、1 和2 的表,您將其連接到包含兩個條目的JSON 數組“fish”,則Fish[0] 匹配0,從而生成一行,並且Fish1 匹配1,導致第二行,但fish[2]為null,因此它與2 不匹配,並且不會在連接中產生行。您需要索引表中的數字與 JSON 資料中任何數組的最大長度一樣多。這有點像駭客,和OP的例子一樣痛苦,但它非常方便。
範例(需要 MySQL 5.7.8 或更高版本):
CREATE TABLE t1 (rec_num INT, jdoc JSON); INSERT INTO t1 VALUES (1, '{"fish": ["red", "blue"]}'), (2, '{"fish": ["one", "two", "three"]}'); SELECT rec_num, idx, JSON_EXTRACT(jdoc, CONCAT('$.fish[', idx, ']')) AS fishes FROM t1 -- Inline table of sequential values to index into JSON array JOIN ( SELECT 0 AS idx UNION SELECT 1 AS idx UNION SELECT 2 AS idx UNION -- ... continue as needed to max length of JSON array SELECT 3 ) AS indexes WHERE JSON_EXTRACT(jdoc, CONCAT('$.fish[', idx, ']')) IS NOT NULL ORDER BY rec_num, idx;
結果是:
+---------+-----+---------+ | rec_num | idx | fishes | +---------+-----+---------+ | 1 | 0 | "red" | | 1 | 1 | "blue" | | 2 | 0 | "one" | | 2 | 1 | "two" | | 2 | 2 | "three" | +---------+-----+---------+
看起來 MySQL 團隊可能會在 MySQL 8 中加入一個 (MySQL 團隊已經新增了JSON_TABLE
函數,以讓這一切變得更容易。 (http://mysqlserverteam.com/mysql-8-0-labs -json-aggregation-functions/)JSON_TABLE
函數。)
P粉4038048442023-08-28 09:32:06
以下是如何使用 JSON_TABLE 在 MySQL 8 中:
SELECT * FROM JSON_TABLE( '[5, 6, 7]', "$[*]" COLUMNS( Value INT PATH "$" ) ) data;
您也可以將其用作 MySQL 所缺少的通用字串分割函數(類似於 PG 的 regexp_split_to_table 或 MSSQL 的 STRING_SPLIT),方法是取得分隔字串並將其轉換為 JSON 字串:
set @delimited = 'a,b,c'; SELECT * FROM JSON_TABLE( CONCAT('["', REPLACE(@delimited, ',', '", "'), '"]'), "$[*]" COLUMNS( Value varchar(50) PATH "$" ) ) data;