iT邦幫忙

0

MYSQL 如何將欄位中的 json 陣列資料拆分出來

  • 分享至 

  • xImage

各位前輩好,
超級菜鳥我又卡關了...TAT,
資料庫的table欄位中有json資料,
上網爬文說可以用split切割出來但一直嘗試失敗,
跪求高手們出手相救...(╥﹏╥)。

原本的table:
month | json
1 | [" 99/01/04", " 99/01/05", " 99/01/06", " 99/01/07"]
2 | [" 99/02/04", " 99/02/05", " 99/02/06", " 99/02/07"]
3 | [" 99/03/04", " 99/03/05", " 99/03/06", " 99/03/07"]

目標的table:
month | date
1 | 99/01/04
1 | 99/01/05
1 | 99/01/06
1 | 99/01/07
2 | 99/02/04
2 | 99/02/05
2 | 99/02/06
2 | 99/02/07
3 | 99/03/04
3 | 99/03/05
3 | 99/03/06
3 | 99/03/07

範例網址:
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c03ca4cc6651415d1069b2a1cd5322b9

範例網址(更新):
https://dbfiddle.uk/I6qunLKC

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3

可以嘗試使用 JSON_EXTRACTJSON_LENGTH 達到你要的結果
範例:
https://stackoverflow.com/a/51035417/9151543
https://stackoverflow.com/a/54673918/9151543

pppppeter iT邦新手 5 級 ‧ 2021-12-10 17:04:59 檢舉

這個好像無法,我的資料沒有keyname :( 。

3
海綿寶寶
iT邦大神 1 級 ‧ 2021-12-10 17:38:48

參考這篇

改出這個 db fiddle
看看合不合用

CREATE TABLE TableDate (
  month INT(20),
  name VARCHAR(100));

INSERT INTO TableDate VALUES
('01','[" 99/01/04", " 99/01/05", " 99/01/06", " 99/01/07"]'),
('02','[" 99/02/04", " 99/02/05", " 99/02/06", " 99/02/07"]'),
('03','[" 99/03/04", " 99/03/05", " 99/03/06", " 99/03/07"]');

CREATE TABLE numbers (
  n INT(20) PRIMARY KEY);

INSERT INTO numbers VALUES 
('01'),('02'),('03'),('04'),('05'),('06'),
('07'),('08'),('09'),('10'),('11'),('12');
SELECT
  TableDate.month,
  REPLACE(REPLACE(SUBSTRING_INDEX(SUBSTRING_INDEX(TableDate.name, '", " ', numbers.n), '", " ', -1),'[" ',''),'"]','') date
FROM
  numbers INNER JOIN TableDate
  ON CHAR_LENGTH(TableDate.name)
     -CHAR_LENGTH(REPLACE(TableDate.name, ',', ''))>=numbers.n-1
ORDER BY
  month, n
pppppeter iT邦新手 5 級 ‧ 2021-12-13 16:36:34 檢舉

這應該是我目前還算看得懂的~,我先來研究~

pppppeter iT邦新手 5 級 ‧ 2021-12-14 17:50:25 檢舉

這方法好像只能用在資料一致的狀況下,真實的資料可能月份日子有十多有時少 TAT,不過還是謝謝大師提供解法,我有撿到新的知識。

4
rogeryao
iT邦超人 8 級 ‧ 2021-12-10 18:07:59
CREATE TABLE TableDate(
month int(20),	
json varchar(500)
)
INSERT TableDate (month,json)
VALUES 
('01','[" 99/01/04", " 99/01/05", " 99/01/06", " 99/01/07"]'),
('02','[" 99/02/04", " 99/02/05", " 99/02/06", " 99/02/07"]'),
('03','[" 99/03/04", " 99/03/05", " 99/03/06", " 99/03/07"]')

資料格式很整齊,就一招

SELECT month,SUBSTRING(json,4,8) AS F1
FROM TableDate
UNION ALL
SELECT month,SUBSTRING(json,17,8) AS F1
FROM TableDate
UNION ALL
SELECT month,SUBSTRING(json,30,8) AS F1
FROM TableDate
UNION ALL
SELECT month,SUBSTRING(json,43,8) AS F1
FROM TableDate
ORDER BY month,F1

Demo

pppppeter iT邦新手 5 級 ‧ 2021-12-13 16:35:26 檢舉

但發問的這資料是我整理過的,原本的資料很醜QQ。

3
一級屠豬士
iT邦大師 1 級 ‧ 2021-12-10 19:05:29
create table it1210 (
  mon int
, js  json
);
-- 宣告為 json 型態.
-- 原發問者是用 varchar(500)

insert into it1210 values 
('01','[" 99/01/04", " 99/01/05", " 99/01/06", " 99/01/07"]'),
('02','[" 99/02/04", " 99/02/05", " 99/02/06", " 99/02/07"]'),
('03','[" 99/03/04", " 99/03/05", " 99/03/06", " 99/03/07"]');

-- 多增加一筆,資料長度不同的.
insert into it1210 values 
('04','[" 99/04/04", " 99/04/05", " 99/04/06", " 99/04/07", " 99/04/08"]');

select i.mon
     , json_extract(js, concat('$[', c.n, ']')) as dt
  from (select @n := @n + 1 as n
          from (select @n := -1) a
             , (select 1
                  from information_schema.CHARACTER_SETS
                 limit 10) b) c
  join it1210 i
 where c.n < json_length(js)
 order by 1,2;

+------+-------------+
| mon  | dt          |
+------+-------------+
|    1 | " 99/01/04" |
|    1 | " 99/01/05" |
|    1 | " 99/01/06" |
|    1 | " 99/01/07" |
|    2 | " 99/02/04" |
|    2 | " 99/02/05" |
|    2 | " 99/02/06" |
|    2 | " 99/02/07" |
|    3 | " 99/03/04" |
|    3 | " 99/03/05" |
|    3 | " 99/03/06" |
|    3 | " 99/03/07" |
|    4 | " 99/04/04" |
|    4 | " 99/04/05" |
|    4 | " 99/04/06" |
|    4 | " 99/04/07" |
|    4 | " 99/04/08" |
+------+-------------+

https://ithelp.ithome.com.tw/upload/images/20211210/20050647oQHIGKP2Ak.png

8版的方法

select i.mon
     , r.res
  from it1210 i
     , json_table(js, '$[*]' columns (res text path '$')) r
 order by 1, 2;

https://ithelp.ithome.com.tw/upload/images/20211210/20050647zgscY75zYb.png

額外說一句,MySQL 都到 8版 已經 N年了, 還在用 5.7.
少了很多好用的函數.

額外說一句,MySQL 都到 8版 已經 N年了, 還在用 5.7.

/images/emoticon/emoticon54.gif

pppppeter iT邦新手 5 級 ‧ 2021-12-13 16:36:02 檢舉

會考慮換成 8版的,感謝你 :D。

我要發表回答

立即登入回答