Đúng là không nên chuẩn hóa thành JSON, nhưng đôi khi bạn cần xử lý dữ liệu JSON và có một cách để trích xuất mảng JSON thành các hàng trong một truy vấn.
Mẹo là thực hiện một phép nối trên một bảng chỉ mục tạm thời hoặc nội dòng, bảng này cung cấp cho bạn một hàng cho mỗi giá trị không rỗng trong một mảng JSON. Tức là nếu bạn có một bảng với các giá trị 0, 1 và 2 mà bạn tham gia vào mảng JSON “fish” với hai mục nhập, thì fish [0] khớp với 0, dẫn đến một hàng và fish 1 khớp với 1, dẫn đến hàng thứ hai, nhưng fish [2] là null nên nó không khớp với 2 và không tạo ra một hàng trong phép nối. Bạn cần bao nhiêu số trong bảng chỉ mục bằng độ dài tối đa của bất kỳ mảng nào trong dữ liệu JSON của bạn. Đó là một chút hack và nó gây đau đớn như ví dụ của OP, nhưng nó rất tiện dụng.
Ví dụ (yêu cầu MySQL 5.7.8 trở lên):
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;
Kết quả là:
+---------+-----+---------+
| rec_num | idx | fishes |
+---------+-----+---------+
| 1 | 0 | "red" |
| 1 | 1 | "blue" |
| 2 | 0 | "one" |
| 2 | 1 | "two" |
| 2 | 2 | "three" |
+---------+-----+---------+
Có vẻ như nhóm MySQL có thể thêm (Nhóm MySQL có đã thêm một JSON_TABLE
trong MySQL 8 để làm cho tất cả điều này dễ dàng hơn. ( http://mysqlserverteam.com/mysql-8-0 -labs-json-aggregation-functions /
) JSON_TABLE
chức năng.)