Can you split/explode a field in a MySQL query?

后端 未结 17 1104
无人及你
无人及你 2020-11-22 04:03

I have to create a report on some student completions. The students each belong to one client. Here are the tables (simplified for this question).

CREATE TAB         


        
17条回答
  •  甜味超标
    2020-11-22 04:35

    You can do this with JSON in more recent MySQL versions. It's a blast. We will have a quick preparation to create a numbers table. Then first we create an intermediary table to convert the comma delimited strings into a json array then we will use json_extract to blast them apart. I am encapsulating the strings in quotes carefully escaping existing quotes because I had semicolon separated strings containing commas.

    So to create the numbers table, hopefully you have more clients than courses, choose an adequately big table if not.

    CREATE TABLE numbers (n int PRIMARY KEY);
    INSERT INTO numbers 
    SELECT @row := @row + 1
    FROM clients JOIN (select @row:=0) t2;
    

    Add LIMIT 50 if you know you only have 50 courses. Now, that was easy, wasn't it? Now on to the real work, honestly it's the quotes that make it uglier but at least it's more generic that way:

    CREATE TABLE json_coursenames 
    SELECT clientId,clientName,CONCAT('["', REPLACE(REPLACE(courseName,'"','\\"'), ',', '","'), '"]') AS a
    FROM clients;
    
    CREATE TABLE extracted
    SELECT clientId,clientName,REPLACE(TRIM(TRIM('"' FROM JSON_EXTRACT(a, concat('$[', n, ']')))), '\\"', '"')
    FROM json_coursenames
    INNER JOIN numbers ON n < JSON_LENGTH(a);
    

    Wheee!

    The meat here are these two: the CONCAT('["', REPLACE(coursename, ',', '","'), '"]') (I dropped the second REPLACE to make it more visible) will convert foo,bar,bar into "foo","bar","baz". The other trick is JSON_EXTRACT(a, concat('$[', n, ']') will become JSON_EXTRACT(a, $[12]) and that's the 13th element in the array, see JSON Path syntax.

提交回复
热议问题