Reputation: 63
Quit struggling a while on this one.
In php I start with some users:
$uids = [1,2,3,4,5];
Then I create different possible week plannings:
$plannings = array
(
1 =>
array(
'friday' => 'cook'
),
2 =>
array(
'friday' => 'cook',
'sunday' => 'play outside'
),
3 =>
array(
'friday' => 'training',
'sunday' => 'training'
),
4 =>
array(
'friday' => 'meeting',
'sunday' => 'brunch'
),
5 =>
array(
'sunday' => 'rest'
)
);
insert them in mysql:
foreach($plannings as $id => $details)
{
INSERT INTO planning (id, data) VALUES ($id, json_encode($details));
}
after that, I assign randomly each user with different planning for the week
$week = [];
foreach($uids as $uid)
{
$week [$uid] = rand(1,5) // which refers to the id of one of the plannings in the plannings array;
}
then I put that into another table saved as JSON
INSERT INTO week (data) VALUES (json_encode($week));
Now it comes, if I want to get the week planning into one array from the DB I can only come up with this dirty solution. for each user included in the week planning I make a new query to retrieve that specific planning
$week = SELECT data FROM week WHERE id = 1
$week = json_decode($week->data);
foreach($week as $uid => $planning_id)
{
$planning = SELECT data FROM planning WHERE id = $planning_id
$week[$uid] = json_decode($planning->data)
}
Now I am kind of silently hoping there could be a way doing this in one simple query using JOINS, JSON_EXTRACT, and other fancy methods in Mysql which I don't know of
Upvotes: 1
Views: 176
Reputation: 2934
If I understand your need correctly, You want to have an INNER JOIN ON values of a two different JSON from 2 different tables.
I assume you use MySQL 8+.
You requirement can be achieved by using JSON_TABLE functions
JSON_TABLE(expr, path COLUMNS (column_list) [AS] alias)
Extracts data from a JSON document and returns it as a relational table having the specified columns.
Lets create tables with a sample data (based on your php codes)
CREATE TABLE `week` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`data` longtext NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO week (data) VALUES ('{"1":2,"2":1,"3":2,"4":1,"5":4}');
CREATE TABLE `planning` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`data` longtext DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO planning (id, data) VALUES (1, '{"friday":"cook"}') ;
INSERT INTO planning (id, data) VALUES (2, '{"friday":"cook","sunday":"play outside"}') ;
INSERT INTO planning (id, data) VALUES (3, '{"friday":"training","sunday":"training"}') ;
INSERT INTO planning (id, data) VALUES (4, '{"friday":"meeting","sunday":"brunch"}') ;
INSERT INTO planning (id, data) VALUES (5, '{"sunday":"rest"}') ;
SELECT * FROM week
will return
id | data |
---|---|
1 | {"1":2,"2":1,"3":2,"4":1,"5":4} |
And SELECT * FROM planning
will return
id | data |
---|---|
1 | {"friday":"cook"} |
2 | {"friday":"cook","sunday":"play outside"} |
3 | {"friday":"training","sunday":"training"} |
4 | {"friday":"meeting","sunday":"brunch"} |
5 | {"sunday":"rest"} |
Now you want to have INNER JOIN on week.data.json_field's_value = planning.id
SELECT
mytable.*,
planning.data
FROM
WEEK,
JSON_TABLE(
JSON_EXTRACT(WEEK.data, '$.*'),
"$[*]" COLUMNS(plan_id INT PATH "$")
) mytable
INNER JOIN planning ON mytable.plan_id = planning.id
Result will be
plan_id | data |
---|---|
2 | {"friday":"cook","sunday":"play outside"} |
1 | {"friday":"cook"} |
2 | {"friday":"cook","sunday":"play outside"} |
1 | {"friday":"cook"} |
4 | {"friday":"meeting","sunday":"brunch"} |
db<>fiddle here
Upvotes: 2