19

I have a JSON field in a MySQL database that contains values like [1,3,4,7]. I would like to be able to easily supply another array from a PHP variable and determine if there is any overlap. I know this example does not work, but this is what I am trying to do:

$DaysVar = $_GET['Days']; --Example is [1,5,8]

$sql = mysqli_query($db, "
    SELECT ScheduleID, 
           Days --Example is [1,3,4,7]
    FROM Schedule
    WHERE JSON_CONTAINS(Days, '$DaysVar')
");

How can I get this query to return a result since there is a 1 in each array?

4
  • please share table data Commented Apr 6, 2017 at 6:18
  • So you want only duplicated values in result? or counter of how many values are duplicated? Commented Apr 6, 2017 at 6:22
  • What version of Mysql are you in? Commented Apr 6, 2017 at 6:24
  • @JorgeCampos JSON_CONTAINS only available in 5.7.8 or later Commented Apr 6, 2017 at 6:25

3 Answers 3

27

On MySQL 5.7.8+ you can perform a JSON_CONTAINS for each separate value:

SELECT * 
FROM   Schedule 
WHERE  (   JSON_CONTAINS(Days, '1')
        OR JSON_CONTAINS(Days, '2')
        OR JSON_CONTAINS(Days, '6')
       )

When the values to be searched for are stored in a PHP variable -- as in your question -- then you could build the above SQL like this:

$DaysVar = $_GET['Days'];
$condition = implode(" OR ", array_map(function($day) {
    return "JSON_CONTAINS(Days, '".intval($day)."')";
}, $DaysVar));
$sql = mysqli_query($db, "
    SELECT ScheduleID, 
           Days
    FROM   Schedule
    WHERE  ($condition)
");

To avoid SQL injection, you should better prepare your statement creating a string like with substr(str_repeat(" OR JSON_CONTAINS(Days, ?)", count($DaysVar)), 3) and then call mysqli_prepare on it, then bind, ...etc.

MySQL 8.*

Since MySQL 8 you can use JSON_OVERLAPS:

SELECT * 
FROM   Schedule
WHERE  JSON_OVERLAPS(Days, '$DaysVar')

Again, you would better prepare the statement (with a ? placeholder), then bind $DaysVar to it, and finally execute it.

Sign up to request clarification or add additional context in comments.

4 Comments

This won't help since the values will be dynamic.
Yeah. I have the same problem with dynamic count of JSON array elements. And I need mysql-only solution. How you fixed this?
Those queries are vulnerable to SQL injection! You need to sanitize day to an int or use prepared statements
🫶 JSON_OVERLAPS saved my afternoon!
2

Probably you found a solution, but for those looking for an answer in the future:

There is now JSON_OVERLAPS(), which in your example you can just swap out for JSON_CONTAINS().

https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#function_json-overlaps

Comments

0

Table :

table details

Sample Data:

enter image description here

In my case, I achieved it with below query if you want data in different row then remove GROUP_CONCAT

Query :

 SELECT *, GROUP_CONCAT(wis.wi) FROM profile_card_stacks,
 JSON_TABLE(work_industry, "$[*]" COLUMNS(wi INT PATH '$')) as wis
 where wis.wi in(10,14);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.