Mariadb查询并提取JSON数据

时间:2018-05-29 11:25:58

标签: json mariadb

我有一个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的结果作为输入。现在我想一想,这似乎是合乎逻辑的,因为这里的“名称”和“得分”是正确排序的,但我能确定它总是那个序列吗?

任何人都可以给我一个如何做得更好的提示吗?

1 个答案:

答案 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