使用 MySQL 转换 JSON 字段
Posted
技术标签:
【中文标题】使用 MySQL 转换 JSON 字段【英文标题】:Transform JSON field with MySQL 【发布时间】:2021-11-30 15:43:07 【问题描述】:我在 tableA 中有一个 JSON 字段,我在其中保存一行从一种状态更改为另一种状态的时刻,就像这样,
row_id | state_history |
---|---|
1 | "2021-09-14 21:00": "State #4", "2021-09-16 21:00": "State #1", "2021-09-17 21:00": "State #6" |
... | ... |
是否可以在 mysql 中使用这个 JSON 来生成一个表,在该表中我可以测量从一种状态变为另一种状态所需的时间?像这样:
row_id | Initial_state | Final_state | Time_diff |
---|---|---|---|
1 | State #4 | State #1 | 2 days |
1 | State #1 | State #6 | 1 day |
2 | State #5 | State #2 | 1 day |
2 | State #2 | State #1 | 4 days |
2 | State #1 | State #6 | 1 day |
... | ... | ... | ... |
请注意,每行的状态数会有所不同。 时差度量单位是分钟、小时还是天并不重要。
对于状态更改部分,我尝试了以下方法,但是这样我只能获得每行的第一个和第二个状态。我不知道如何制作时差部分。
SELECT A.row_id, A.state ->> '$[0]' AS Initial_state, A.state ->> '$[1]' AS Final_state
FROM
(SELECT
row_id,
state_history -> '$.*[0]' AS state
FROM
tableA) A
如果可能,按状态对(Initial_state、Final_state)进行分组,这样我就可以有一个指标来计算从特定状态变为另一个状态所需的平均时间。
【问题讨论】:
【参考方案1】:WITH cte1 AS (
SELECT test.row_id,
jsontable.`date`,
JSON_UNQUOTE(JSON_EXTRACT(test.state_history, CONCAT('$."', jsontable.`date`, '"'))) state
FROM test
CROSS JOIN JSON_TABLE(JSON_KEYS(state_history),
'$[*]' COLUMNS (`date` VARCHAR(64) PATH '$')) jsontable
),
cte2 AS (
SELECT row_id,
LAG(state) OVER (PARTITION BY row_id ORDER BY `date`) Initial_state,
state Final_state,
DATEDIFF(`date`, LAG(`date`) OVER (PARTITION BY row_id ORDER BY `date`)) Time_diff,
`date`
FROM cte1
)
SELECT row_id,
CAST(Initial_state AS CHAR) Initial_state,
CAST(Final_state AS CHAR) Final_state,
Time_diff
FROM cte2
WHERE Initial_state IS NOT NULL
ORDER BY row_id, `date`
step-by-step fiddle
【讨论】:
解决了问题,谢谢!以上是关于使用 MySQL 转换 JSON 字段的主要内容,如果未能解决你的问题,请参考以下文章
查询Mysql表之后将结果转换为json时如何能够保持字段的原有数据类型?