Update mysql row based on same ID condition - mysql

I have a MySql table (locations) that looks this:
locations
+-------+---------+--------+-------------------------------------------------------------+
| id | street | number | geoloc |
+-------+---------+--------+-------------------------------------------------------------+
| 10 | street1 | 1 | {"type": "Point", "coordinates": [-95.31231, 21.41241]} |
| 1000 | street2 | 2 | {"type": "Point", "coordinates": [9312.31231, 8231.41241]} |
| 1000 | street2 | 2 | {"type": "Point", "coordinates": [-95.45342, 21.44423]} |
| 10 | street1 | 1 | {"type": "Point", "coordinates": [312.31231, 33231.41241]} |
| 10 | street1 | 1 | {"type": "Point", "coordinates": [4312.31231, 3231.41241]} |
| 10000 | street3 | 3 | {"type": "Point", "coordinates": [-95.31271, 21.41312]} |
+-------+---------+--------+-------------------------------------------------------------+
Now the problem is that some of the location's have wrong geoloc values, and the rule to filter wrong values/good values is that some x,y coordinates are valid (ex. -95.31231, 21.41241) and some don't (ex. 4312.31231, 3231.41241). The filter pattern for good values should be this format (-95.xxxxxx, 21.xxxxxx).
The end result after update should be exactly this:
locations
+-------+---------+--------+-------------------------------------------------------------+
| id | street | number | geoloc |
+-------+---------+--------+-------------------------------------------------------------+
| 10 | street1 | 1 | {"type": "Point", "coordinates": [-95.31231, 21.41241]} |
| 1000 | street2 | 2 | {"type": "Point", "coordinates": [-95.45342, 21.44423]} |
| 1000 | street2 | 2 | {"type": "Point", "coordinates": [-95.45342, 21.44423]} |
| 10 | street1 | 1 | {"type": "Point", "coordinates": [-95.31231, 21.41241]} |
| 10 | street1 | 1 | {"type": "Point", "coordinates": [-95.31231, 21.41241]} |
| 10000 | street3 | 3 | {"type": "Point", "coordinates": [-95.31271, 21.41312]} |
+-------+---------+--------+-------------------------------------------------------------+
What I'm trying to do is this:
UPDATE locations l1, (
SELECT DISTINCT id, geoloc
FROM locations
WHERE geoloc IS NOT NULL
) l2 SET l1.geoloc = l2.geoloc
WHERE l1.id = l2.id;
And I'm not sure that WHERE is actually matching by my desired output.

UPDATE locations l1, (
SELECT DISTINCT id, geoloc <-- This will always return all rows
FROM locations
WHERE geoloc IS NOT NULL
) l2 SET l1.geoloc = l2.geoloc
WHERE l1.id = l2.id;
Also the update would be arbitrary.
You should try something like this.
UPDATE locations l1, locations l2
SET l1.geoloc = l2.geoloc
WHERE l1.id = l2.id
and l1. geoloc <> l2.geoloc
and ST_X(l2.geoloc) like '%-95.%';

Related

Merging Variant rows in Snowflake

I have a table structure in snowflake with variant data type as shown below, you can see the a single ID is having multiple variant objects.
+-----+--------------------------+
| ID | STATE_INFO |
|-----+--------------------------|
| IND | { |
| | "population": "1000k", |
| | "state": "KA" |
| | } |
| IND | { |
| | "population": "2000k", |
| | "state": "AP" |
| | } |
| IND | { |
| | "population": "3000K", |
| | "state": "TN" |
| | } |
| US | { |
| | "population": "100k", |
| | "state": "Texas" |
| | } |
| US | { |
| | "population": "200k", |
| | "state": "Florida" |
| | } |
| US | { |
| | "population": "300K", |
| | "state": "Iowa" |
| | } |
+-----+--------------------------+
I want to combine these variant objects into a single object like below by merging the rows into one array or dictionary object
+-----+---------------------------+
| ID | STATE_INFO |
|-----+---------------------------|
| IND | [{ |
| | "population": "1000k", |
| | "state": "KA" |
| | }, |
| | { |
| | "population": "2000k", |
| | "state": "AP" |
| | }, |
| | { |
| | "population": "3000K", |
| | "state": "TN" |
| | }] |
| US | [{ |
| | "population": "100k", |
| | "state": "Texas" |
| | }, |
| | { |
| | "population": "200k", |
| | "state": "Florida" |
| | }, |
| | { |
| | "population": "300K", |
| | "state": "Iowa" |
| | }] |
+-----+---------------------------+
Like in SQL terminologies, we can say like below SQL statement
Select id,merge(STATE_INFO) from table group by id;
Like Mike said ARRAY_AGG function is what you need and it works on a variant column
select id, array_agg(STATE_INFO) within group (order by id) STATE_INFO
from table
group by 1
order by 1
Using this CTE for data:
With data(id, state_info) as (
select column1, parse_json(column2)
from values
('IND', '{ "population": "1000k", "state": "KA" }'),
('IND', '{ "population": "2000k", "state": "AP" }'),
('IND', '{ "population": "3000K", "state": "TN" }'),
('US', '{ "population": "100k", "state": "Texas" }'),
('US', '{ "population": "200k", "state": "Florida" }'),
('US', '{ "population": "300K", "state": "Iowa" }')
)
This code is is almost exactly the same is demircioglu's answer, but has no ordering of the array content.
select id, array_agg(state_info) as stateinfo
from data
group by 1;
which because of the order of the input still appears ordered. But it is really random, it depends if you need the data ordered or not:
ID
STATEINFO
US
[ { "population": "100k", "state": "Texas" }, { "population": "200k", "state": "Florida" }, { "population": "300K", "state": "Iowa" } ]
IND
[ { "population": "1000k", "state": "KA" }, { "population": "2000k", "state": "AP" }, { "population": "3000K", "state": "TN" } ]

How to generate n-level hierarchical JSON from Spark DataFrame

Given the following Spark dataframe:
+----+-----------+------+-------+
| id | parent_id | data | level |
+----+-----------+------+-------+
| 1 | null | x | 1 |
| 21 | 1 | y | 2 |
| 22 | 1 | w | 2 |
| 31 | 21 | z | 3 |
+----+-----------+------+-------+
Where 'level' means the level in a tree-like structure.
How can I generate a n-level hierarchical JSON?
{
"id": "1",
"data": "x",
"items": [
{
"id": "21",
"data": "y",
"items": [
{
"id": "31",
"data": "z",
"items": []
}
]
},
{
"id": "22",
"data": "w",
"items": []
}
]
}

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.

Extract key, value from columns field in Postgresql table

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;

How to use MySQL select statement to generate rows for each entry in a JSON list?

I have a JSON column in a MySQL table.
A column contains a list of dictionaries. I would like for each item in the list to get it's own row, with the row ID. See the example below for better understanding.
Example:
mysql> select id, geography from region;
+------|-------------------------------------------------------------------------------------------------------------+
| id | geography |
+------|-------------------------------------------------------------------------------------------------------------+
| 1 | [{"state": "SC", "county": "BERKELEY"}}] |
| 2 | [{"county": "Placer", "state": "CA"}, {"county": "Sacramento", "state": "CA"}] |
| 3 | [{"county": "Jeff", "state": "MO"},{"county": "Charles", "state": "MO"},{"county": "Louis", "state": "MO"}] |
+------|-------------------------------------------------------------------------------------------------------------+
Desired output:
+------|--------------|-------------+
| id | county | state |
+------|--------------|-------------|
| 1 | BERKELEY | SC |
| 2 | Placer | CA |
| 2 | Sacramento | CA |
| 3 | Jeff | MO |
| 3 | Charles | MO |
| 3 | Louis | MO |
+------|--------------|-------------+
It seems to be a bad idea to do that, but sometimes you have to, I guess.
3 options come to mind:
If you're using MySQL >=5.7.8, use internal JSON-related functions
JSON UDF for MySQL
Use common_schema
Your best shot would probably be 3rd option. You should lookup common_schema.extract_json_value().