Extract key, value from columns field in Postgresql table - json

id | columns | timestamp | query_id | task_id
-------+----------------------------------------------+----------------------------+----------------------+---------------------------
1 | {"uid": "112", "name": "redis-server"} | 2018-07-18 18:45:39.045387 | 1 | 2
2 | {"uid": "0", "name": "celery"} | 2018-07-18 18:45:39.047671 | 1 | 2
3 | {"uid": "111", "name": "post"} | 2018-07-18 18:45:39.048218 | 1 | 2
4 | {"uid": "111", "name": "post"} | 2018-07-18 18:45:39.048732 | 1 | 2
Looking to extract normal values from json for UID & NAME through query syntax

You can use JSON operator ->>. ie:
select *, "columns"->>'uid' as uid, "columns"->>'name' as name
from myTable;

Related

Problem with the sorting in MYSQL with use INNER JOIN

I have problem with query, I can't corretly write sorting with method INNER JOIN. I Have three tables:
PRODUCT:
+----+---------------------------------+------------+
| id | name | created_at |
+----+---------------------------------+------------+
| 1 | Broth | 1673625572 |
| 2 | Skyr | 1673982452 |
| 3 | Hamburger | 1674060883 |
+----+---------------------------------+------------+
INGREDIENT
+----+---------+------------+
| id | name | created_at |
+----+---------+------------+
| 1 | kcal | 1673982085 |
| 2 | Protein | 1673982085 |
+----+---------+------------+
and table with relations:
+----+------------+---------------+--------+----------+-------------+------------+
| id | product_id | ingredient_id | value | priority | modified_at | created_at |
+----+------------+---------------+--------+----------+-------------+------------+
| 1 | 2 | 1 | 389.00 | 1 | 1673983108 | 1673983108 |
| 2 | 2 | 2 | 71.00 | 1 | 1673983183 | 1673983183 |
| 3 | 1 | 2 | 59.00 | 1 | 1674059830 | 1674059830 |
| 4 | 1 | 1 | 394.00 | 1 | 1674059875 | 1674059875 |
| 5 | 3 | 1 | 366.00 | 1 | 1674060944 | 1674060944 |
| 6 | 3 | 2 | 76.00 | 1 | 1674060944 | 1674060944 |
+----+------------+---------------+--------+----------+-------------+------------+
This is my query:
SELECT
`product`.`name` AS `name`,
JSON_ARRAYAGG(JSON_OBJECT('name', `ingredient`.`permalink`, 'value', `_related_product_ingredient`.`value` )) AS `ingredients`
FROM
`_related_product_ingredient`
INNER JOIN
`product` ON `product`.`id` = `_related_product_ingredient`.`product_id`
INNER JOIN
`ingredient` ON `ingredient`.`id` = `_related_product_ingredient`.`ingredient_id`
GROUP BY `_related_product_ingredient`.`product_id`;
This is a result
+---------------------------------+--------------------------------------------------------------------------+
| name | ingredients |
+---------------------------------+--------------------------------------------------------------------------+
| Broth | [{"name": "protein", "value": 59.00}, {"name": "kcal", "value": 394.00}] |
| Skyr | [{"name": "protein", "value": 71.00}, {"name": "kcal", "value": 389.00}] |
| Hamburger | [{"name": "protein", "value": 76.00}, {"name": "kcal", "value": 366.00}] |
+---------------------------------+--------------------------------------------------------------------------+
I would like my result to be sorted by protein value from highest to lowest.
Any advice?
You can sort the result by protein value by adding the following line to your query:
ORDER BY
JSON_EXTRACT(ingredients, '$[1].value') DESC;
So the complete query would be:
SELECT
product.name AS name,
JSON_ARRAYAGG(JSON_OBJECT('name', ingredient.permalink, 'value', _related_product_ingredient.value )) AS ingredients
FROM
_related_product_ingredient
INNER JOIN
product ON product.id = _related_product_ingredient.product_id
INNER JOIN
ingredient ON ingredient.id = _related_product_ingredient.ingredient_id
GROUP BY _related_product_ingredient.product_id
ORDER BY
JSON_EXTRACT(ingredients, '$[1].value') DESC;
This will sort the results by the value of the second element in the ingredients array, which should correspond to the protein value.

Fetching value in the json array in MySQL, Laravel

I have that kinda table and data :
Table Name : data
+------+-----------------+--------+----------+
| id | number | name | surname |
+------+-----------------+--------+----------+
| 1 | [1, 2, 3, 4, 5] | John | Doe |
| 2 | [1, 2, 4, 8] | James | Webb |
| 3 | [3, 4, 5] | Jenny | Test |
+------+-----------------+--------+----------+
For example, I want to fetch the rows in the number column with the value 3 :
+------+-----------------+--------+----------+
| id | number | name | surname |
+------+-----------------+--------+----------+
| 1 | [1, 2, 3, 4, 5] | John | Doe |
| 3 | [3, 4, 5] | Jenny | Test |
+------+-----------------+--------+----------+
I tried that with Laravel but didn't work. :
DB::table('data')
->whereRaw('FIND_IN_SET(?, number)', [3])
->get();
How can I solve that problem? Thanks for your answers.
You can use toJson(), to convert the collection to json object in Laravel.
$_data = DB::table('data')
->whereRaw('FIND_IN_SET(?, number)', [3])
->get()->toJson();
dd($_data);
Have a look at the [documentation] https://laravel.com/docs/9.x/responses#json-responses
Thanks for your answers. I found the answer to my question as follows :
I made the Array values as strings. Like that :
Table Name : data
+------+---------------------------+--------+----------+
| id | number | name | surname |
+------+---------------------------+--------+----------+
| 1 | ["1", "2", "3", "4", "5"] | John | Doe |
| 2 | ["1", "2", "4", "8"] | James | Webb |
| 3 | ["3", "4", "5"] | Jenny | Test |
+------+---------------------------+--------+----------+
And then I used to this codes. :
$_data = DB::table('data')
->where('number', 'LIKE', '%"' . "3" . '"%')
->get();
Also you can do with SQL commands. Like that :
SELECT *
FROM data
WHERE number LIKE '%"3"%';
Exactly like I want, it turned to me this :
+------+---------------------------+--------+----------+
| id | number | name | surname |
+------+---------------------------+--------+----------+
| 1 | ["1", "2", "3", "4", "5"] | John | Doe |
| 3 | ["3", "4", "5"] | Jenny | Test |
+------+---------------------------+--------+----------+

From differents columns create a new one with a json format

I'm a stuck with pandas. i have two df like that :
index | seller | sales | is_active
:-----: |--------|---------|-----------
0 | smith | Yes | Yes
1 | john | No | Yes
2 | alan | Yes | No
and an other one :
index | seller | product | EAN | URL | PRICE |
:-----: |--------|---------|-------------|----------------|:----------:|
0 | smith | book | ANUDH17e89 | www.ecvdgv.com | 13.45
1 | smith | dvd | NVGS5w621 | www.awfcj.com | 23.76
2 | smith | cd | NCYbh658 | www.bstx.com | 9.99
3 | john | sofa | codkv32876 | www..... | 348
4 | john | umbrella| chudbic132 | www..... | 38
5 | john | bag | coGTTf276 | www..... | 54
6 | alan | tv | BYU1890H | www..... | 239
7 | alan | cable | ndhnjh0988 | www..... | 5
8 | alan | fridge | BTFS$42561 | www..... | 158
And i would like to do a left join on the first df and create a column as a json wit the differents informations in a new column as a json. Ssomething like that :
index | seller | sales | is_active | New_column
:-----: |--------|---------|-----------|-----------
0 | smith | Yes | Yes | {product : book,
EAN : ANUDH17e89,
URL : www.ecvdgv.com,
Price : 13,45} ,
{product :dvd,
EAN : NVGS5w621,
URL : www.awfcj.com,
Price : 23,76},
etc..
and the same for each seller
Hope is clear
Thanks or your help !
Try:
import json
df2["New_column"] = df2.apply(lambda x: json.dumps(x.to_dict()), axis=1)
out = df1.merge(
df2[["seller", "New_column"]]
.groupby("seller")
.agg(", ".join)
.reset_index(),
on="seller",
)
print(out)
Prints:
seller sales is_active New_column
0 smith Yes Yes {"seller": "smith", "product": "book", "EAN": "ANUDH17e89", "URL": "www.ecvdgv.com", "PRICE": 13.45}, {"seller": "smith", "product": "dvd", "EAN": "NVGS5w621", "URL": "www.awfcj.com", "PRICE": 23.76}, {"seller": "smith", "product": "cd", "EAN": "NCYbh658", "URL": "www.bstx.com", "PRICE": 9.99}
1 john No Yes {"seller": "john", "product": "sofa", "EAN": "codkv32876", "URL": "www.....", "PRICE": 348.0}, {"seller": "john", "product": "umbrella", "EAN": "chudbic132", "URL": "www.....", "PRICE": 38.0}, {"seller": "john", "product": "bag", "EAN": "coGTTf276", "URL": "www.....", "PRICE": 54.0}
2 alan Yes No {"seller": "alan", "product": "tv", "EAN": "BYU1890H", "URL": "www.....", "PRICE": 239.0}, {"seller": "alan", "product": "cable", "EAN": "ndhnjh0988", "URL": "www.....", "PRICE": 5.0}, {"seller": "alan", "product": "fridge", "EAN": "BTFS$42561", "URL": "www.....", "PRICE": 158.0}

Retrieve many to many relation with laravel eloquent

I'm trying to retrieve data from many to many relation grouped in one object for the duplicated date.
I have menu table and daily_mealz table and pivot table(menu_daily_mealz)
the problem is the daily_mealz contain duplicated date value in its date column but every raw contain different meal_id.
So, I need to retrieve one raw but contain all mealsIDs related to this date
I only retrieve with belongsTo relation and them for loop over the data to get the object I need.
Relations
public function dailyMeals(){
return $this->belongsToMany(DailyMeals::class, 'menu_daily_meals', 'menu_id', 'daily_meal_id');
}
public function menus(){
return $this->belongsToMany(Menu::class, 'menu_daily_meals', 'daily_meal_id', 'menu_id');
}
DataBase Structure
Menu table
+-----+----------------+
| id | name |
+-----+----------------+
| 1 | first menu |
| 2 | second menu |
+-----+----------------+
daily mealz table
+----+-------------+---------+-------+
| id | date | meal_id | stock |
+----+-------------+---------+-------+
| 1 | 2019-03-01 | 1 | 250 |
| | | | |
| 2 | 2019-03-01 | 2 | 100 |
| | | | |
| 3 | 2019-03-02 | 3 | 150 |
| | | | |
| 4 | 2019-03-02 | 4 | 70 |
| | | | |
| 5 | 2019-03-03 | 5 | 350 |
| | | | |
| 6 | 2019-03-03 | 6 | 180 |
+----+-------------+---------+-------+
Menu_daily_meals table
+----+---------+---------------+
| id | menu_id | daily_meal_id |
+----+---------+---------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 1 | 4 |
| 5 | 1 | 5 |
| 6 | 1 | 6 |
| 7 | 2 | 3 |
| 8 | 2 | 5 |
| 9 | 2 | 6 |
+----+---------+---------------+
I need to retrieve object like that
{
"id": 1,
"name": "first menu",
"daily_meals": [
{
"id": 1,
"daily_date": "2019-03-01",
"meals" : [
{
"meal_id" : 1,
"stock" : 250
},
{
"meal_id" : 2,
"stock" : 100
},
]
},
{
"id": 2,
"daily_date": "2019-03-02",
"meals" : [
{
"meal_id" : 3,
"stock" : 150
},
{
"meal_id" : 4,
"stock" : 70
},
]
},
{
"id": 3,
"daily_date": "2019-03-03",
"meals" : [
{
"meal_id" : 5,
"stock" : 350
},
{
"meal_id" : 6,
"stock" : 180
},
]
}
]
}
Any Help, Please?
You should use load function to load external data to your model(use eager loading):
$menu=Menu::find(1);
$menu->load('dailyMeals','dailyMeals.meals');
Note : For hide pivot object in response add this code to your menu model:
protected $hidden = ['pivot'];
Note : You should have dailyMeals in your menu model and meals relation in your dailyMeals model
For more information You can Visit Laravel Document.

Replace subset of MySQL records

I have a MySQL database called ice_cream with three tables, users, flavors, and favorites. Each record in favorites has a reference to a user and a flavor, and a user is able to have multiple ice cream flavors.
I'm trying to write a transaction to completely replace a user's favorites with another set of favorites. For example, when the API accepts
PUT /user/100/favorites
{
"flavors": {
"2": { "stars": 2 },
"3": { "stars": 5, "comments": "Changed my life" },
"18": { "stars": 4, "comments": "👅 " },
"24": { "stars": 4 }
}
}
The favorites table should change from
| id | user_id | flavor_id | stars | comments |
| --- | ------- | --------- | ----- | ------------------ |
| 200 | 100 | 2 | 2 | Tastes OK |
| 201 | 100 | 4 | 3 | |
| 202 | 100 | 5 | 3 | |
To
| id | user_id | flavor_id | stars | comments |
| --- | ------- | --------- | ----- | ------------------ |
| 200 | 100 | 2 | 2 | |
| 201 | 100 | 3 | 5 | Changed my life |
| 203 | 100 | 18 | 4 | 👅 |
| 204 | 100 | 24 | 4 | |
What's the most efficient set of statements to accomplish this?
Points to consider:
I'm not concerned with keeping primary ids consistent.
The users are really into the small-batch craft ice cream scene and will usually replace about 5000 records each transaction.
in this case the most efficient set of statements is delete and insert
delete from flavors
where user_id =100;
and a loop server side for insert the new values or a batch insert with all the values in repated values rows
insert into flavors ( user_id, flavor_id, stars , comments )
values ( 100,2 ,2 null),
(100, 3, 5 , 'Changed my life'),
(100 ,18,4 , 👅 ),
(100 , 24 ,4 , null)