1
{
    "tr_no": "2",
    "actions": [
        {
            "link_type": "1"
            "tr_link": "www.abc.com"
        },
                    {
            "link_type": "1"
            "tr_link": "www.def.com"
        },
                   {
            "link_type": "1"
            "tr_link": "www.abc.com"
        }
    ]
}

How can I remove the duplicated "actions" objects by considering "tr_link" using a MySQL query and update the all records in the table that this column has?

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
xcxc0
  • 99
  • 1
  • 9

1 Answers1

1

Tested on MySQL 8.0.29:

with cte (actions) as (
  select json_arrayagg(json_object('link_type', link_type, 'tr_link', tr_link)) 
  from (
    select distinct j.* from mytable 
    cross join json_table(data, '$.actions[*]' columns(
      link_type varchar(10) path '$.link_type', 
      tr_link varchar(50) path '$.tr_link')) as j
  ) as d
) 
update mytable cross join cte 
set data = json_set(data, '$.actions', cte.actions);

Re your comments:

I tested the query above after changing the column to LONGBLOB, and I got this error:

ERROR 3144 (22032): Cannot create a JSON value from a string with CHARACTER SET 'binary'.

So it appears you can't use MySQL's built-in JSON functions on binary data.

This explains why your sample JSON in your question above is invalid JSON format (lacking commas between object fields). If you were using MySQL's JSON data type, you could not store invalid JSON.

So it seems you can't use SQL to eliminate the duplicates. You should fetch the whole JSON document into a client application, deserialize it, remove duplicates with whatever code you want, and then re-serialize it to JSON (hopefully valid JSON this time), and save it back to the database.

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • Thank you for your answer. I have an issue that the data type is defined as LONGBLOB for the column these JSONs should be saved. Then how can I update the data? – xcxc0 Aug 26 '22 at 18:08
  • Why aren't you using the [JSON data type](https://dev.mysql.com/doc/refman/8.0/en/json.html)? – Bill Karwin Aug 26 '22 at 18:11
  • This table is currently in the production environment. So I think this table structure won't be changed again. I just got to update some incorrectly migrated records in this table. – xcxc0 Aug 26 '22 at 18:15
  • To overcome ERROR 3144, I used CONVERT(actions USING utf8mb4). After that, I got a new error Error Code: 3141 to overcome that I used JSON_VALID(CONVERT(answers USING utf8mb4)) then your above query worked for me. Thank you very much. – xcxc0 Aug 27 '22 at 02:20