0

I have a table where the content column consists of a JSON object, with an example value:

{"blocks":[{"score":"A"},{"score":"A"},{"score":"B"}]}

What I am trying to do is SELECT for a string representation of all the scores, so for this example I want:

AAB

I have been able to parse the JSON easily:

SELECT json_extract(content, '$.blocks[*].score') AS scores

Which results in:

["A", "A", "B"]

but for some reason I'm having an issue concatenating that JSON array into a single string (aside from casting it as a string and calling a few replace functions to remove the quotes and brackets). I've tried variations of CONCAT and GROUP_CONCAT but have not found a solution.

What is the proper way to concatinate this JSON string into a single string?

Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55
Chris Schlitt
  • 133
  • 3
  • 12
  • I don't think there's a built-in MySQL function that will join an array into a string. – Barmar Feb 02 '21 at 20:59
  • If you normalized your schema instead of using JSON you could use `GROUP_CONCAT()`. – Barmar Feb 02 '21 at 21:00
  • In my observation, most questions about using JSON in MySQL could be answered: "this would be a lot easier if you didn't use JSON." – Bill Karwin Feb 02 '21 at 22:26

1 Answers1

0

You can use a catalog table such as information_schema.tables in order to generate rows to iterate by the length of the array, and then aggregate all members by using GROUP_CONCAT() such as

SELECT GROUP_CONCAT(
                    JSON_UNQUOTE(
                       JSON_EXTRACT(content,
                                    CONCAT('$.blocks[', i - 1, '].score'))
                                   ) 
                       SEPARATOR '') AS scores
  FROM (SELECT JSON_LENGTH(JSON_EXTRACT(content, '$.blocks[*].score')) AS len,
               @i := @i + 1 AS i,
               content
          FROM tab
          JOIN information_schema.tables
          JOIN (SELECT @i := 0) AS i) AS t
 WHERE i <= len;

+--------+
| scores |
+--------+
|  AAB   |
+--------+

Demo

Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55