我有一个MaraiDB(10.2.14)数据库,其中包含一个表,其中存储了一列JSON数据。
我很困惑如何从这个专栏中提取数据。
示例数据
SELECT 1 AS ID
, '[{"name":"x","score":2},{"name":"y", "score":8},{"name":"z","score":3}]' AS REPLY
UNION ALL
SELECT 2 AS ID
, '[{"name":"x","score":5},{"name":"y", "score":4},{"name":"z","score":3}]' AS REPLY
UNION ALL
SELECT 3 AS ID
, '[{"name":"x","score":2},{"name":"y", "score":2},{"name":"z","score":6}]' AS REPLY
UNION ALL
SELECT 4 AS ID
, '[{"name":"x","score":5},{"name":"y", "score":8},{"name":"z","score":6}]' AS REPLY
那么如何找到所有具有“名称”的条目:“x”和“得分”:5。另外,我需要得到“名称”的“得分”值:该条目的“y”。
我目前的肮脏方法是
WITH JT1 AS (
SELECT 1 AS ID
, '[{"name":"x","score":2},{"name":"y", "score":8},{"name":"z","score":3}]' AS REPLY
UNION ALL
SELECT 2 AS ID
, '[{"name":"x","score":5},{"name":"y", "score":4},{"name":"z","score":3}]' AS REPLY
UNION ALL
SELECT 3 AS ID
, '[{"name":"x","score":2},{"name":"y", "score":2},{"name":"z","score":6}]' AS REPLY
UNION ALL
SELECT 4 AS ID
, '[{"name":"x","score":5},{"name":"y", "score":8},{"name":"z","score":6}]' AS REPLY
)
SELECT ID
, REGEXP_REPLACE(
REGEXP_REPLACE( EXTRACTED, '^.*"y",\\s', '')
, '[,\\]].*$', '') AS Y
, EXTRACTED
FROM (
SELECT ID
, JSON_EXTRACT(REPLY, '$[*].name','$[*].score') EXTRACTED
FROM JT1
) JT2
WHERE EXTRACTED RLIKE '"x", 5\\b'
;
所以我首先提取“名称”和“得分”,它给出了像["x", 5, "y", 4, "z", 3]
这样的列数据。有了这个我做了一些讨厌的REGEXP搜索&取代
我觉得必须有更好的方法。
我尝试使用COLUMN_CREATE,但“COLUMN_CREATE”似乎无法接受来自JSON_EXTRACT的结果作为输入。现在我想一想,这似乎是合乎逻辑的,因为这里的“名称”和“得分”是正确排序的,但我能确定它总是那个序列吗?
任何人都可以给我一个如何做得更好的提示吗?
答案 0 :(得分:1)
如果我了解您的需求,则如下查询可能会有用:
WITH `JT1` AS (
SELECT 1 AS `ID`
, '[{"name":"x","score":2},{"name":"y", "score":8},{"name":"z","score":3}]' AS `REPLY`
UNION ALL
SELECT 2 AS `ID`
, '[{"name":"x","score":5},{"name":"y", "score":4},{"name":"z","score":3}]' AS `REPLY`
UNION ALL
SELECT 3 AS `ID`
, '[{"name":"x","score":2},{"name":"y", "score":2},{"name":"z","score":6}]' AS `REPLY`
UNION ALL
SELECT 4 AS `ID`
, '[{"name":"x","score":5},{"name":"y", "score":8},{"name":"z","score":6}]' AS `REPLY`
)
SELECT
`ID`,
`REPLY`,
JSON_VALUE(
`REPLY`,
JSON_UNQUOTE(
REPLACE(
JSON_SEARCH(`REPLY`, 'one', 'y', NULL, '$[*].name'),
'name',
'score'
)
)
) `"name":"y"`
FROM
`JT1`
WHERE
JSON_VALUE(
`REPLY`,
JSON_UNQUOTE(
REPLACE(
JSON_SEARCH(`REPLY`, 'one', 'x', NULL, '$[*].name'),
'name',
'score'
)
)
) = 5;
请参见dbfiddle。