Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySql 5.7 json_extract by key

Tags:

json

mysql

I have a table and it looks like below:

Table data

id params
1  {"company1X":{"price":"1124.55"},"company2X":{"price":"1,124.55"},"company3X":{"price":""},"company4X":{"price":""},"company5X":{"price":"1528.0"}}

I don't know the name of "company" to use in my request.

How can I fetch my data ordered by price? Thanks!

P.S I have tried select json_extract(params, '$[*].price') from data but it doesn't work (return nulls).

like image 664
XTRUST.ORG Avatar asked Dec 18 '22 07:12

XTRUST.ORG


1 Answers

$[*] gets all elements of a JSON array, not an object. This is an object, so you get NULL.

$.* will get you all elements in a JSON object, so $.*.price gets you a JSON array of all prices.

mysql> select json_extract(params, '$.*.price') from foo;
+-------------------------------------------+
| json_extract(params, '$.*.price')         |
+-------------------------------------------+
| ["1124.55", "1,124.55", "", "", "1528.0"] |
+-------------------------------------------+

Now there's a problem. As far as SQL is concerned, this is a single row. It can't be sorted with a normal order by, that works on rows.

MySQL has no function for sorting JSON... so you're stuck. You can return the JSON array and let whatever is receiving the data do the sorting. You might be able to write a stored procedure to sort the array... but that's a lot of work to support a bad table design. Instead, change the table.


The real problem is this is a bad use of a JSON column.

JSON columns defeat most of the point of a SQL database (less so in PostgreSQL which has much better JSON support). SQL databases work with rows and columns, but JSON shoves what would be multiple rows and columns into a single cell.

For this reason, JSON columns should be used sparingly; typically when you're not sure what sort of data you'll be needing to store. Important information like "price" that's going to be searched and sorted should be done as normal columns.

You'll want to change your table to be a normal SQL table with columns for the company name and price. Then you can use normal SQL features like order by and performance will benefit from indexing. There isn't enough information in your question to suggest what that table might look like.

like image 136
Schwern Avatar answered Jan 11 '23 03:01

Schwern