Want to get relational table value in specified way in mysql - php

I have 2 table like below.
Table A
id | val_a
1 | a1
2 | a2
3 | a3
Table B
id | id_a| val_b
1 | 2 | b1
2 | 2 | b2
3 | 3 | b3
What is the best way to get data like below :
[
[0] => stdClass Object
(
[id_a] => 1
[val_a] => 'a1'
)
[1] => stdClass Object
(
[id_a] => 2
[val_a] => 'a2'
[table_b] => Array
(
[0] => stdClass Object
(
[id_b] => 1
[val_b] => 'b1'
)
[1] => stdClass Object
(
[id_b] => 2
[val_b] => 'b2'
)
)
)
[2] => stdClass Object
(
[id_a] => 3
[val_a] => 'a3'
[table_b] => Array
(
[0] => stdClass Object
(
[id_b] => 3
[val_b] => 'b3'
)
)
)
]
I am using Laravel 5.2. And achive this by foreach loop. But I don't know what is the best way to do. Can I do this by laravel or Mysql ? Thanks Ahead.

You can achieve this using Eloquent Model and hasMany relationship
for the first table Table A
class table_a extends Model
{ //define your primary key
protected $primaryKey = 'id_a'; /*you can skip this if id is your primary key*/
public function get_b_values(){
return $this->hasMany(table_b::class, 'id_b', 'id_a');
//foreign_key then local_key
}
}
for the second table Table B
class table_b extends Model
{
protected $primaryKey = 'id_b';
/*you can skip this if id is your primary key*/
}
Then you can access the element (exp id=2) you want like this:
table_a::find(2)->get_b_values;
UPDATE
Try this in your controller:
$results=table_a::with('get_b_values')->get();

Yes you can do it using laravel, take data from table_a and store row in a variable and run another query in table_b where id_a = id (table_a's id column) and store them into your defined variable.

Related

How to create a three dimensional array from sql query PHP

I have 2 tables in a database, 1 of them are linked with a foreign key to the first one. Each row on table 1 is linked to multiple rows in table 2. I am trying to make a query that looks at a WHERE from table 2 and returns multiple rows from table 2 which are sorted into the rows they linked with in table 1 and then put this all into one big multi dimensional array, so it should work something like this:
$array[0][column_name][0] this would use row 1 from table 1 and give me a the first result in the column called column_name
$array[1][column_name][0] this would use row 2 from table 1 and give me a the first result in the column called column_name
$array[1][column_name][3] this would use row 2 from table 1 and give me a the 4th result in the column called column_name
etc
How can I query this and store it in a 3 dimensional array using PHP.
I have tried to word this in as clear manner as possible, if you are unsure what I am asking, please comment and I will update my question to make it clearer.
Assume that we have two tables, Company and Employee:
Company
------------------
ID Company_Name
1 Walmart
2 Amazon.com
3 Apple
Employee
---------------------------------
ID Company_Id Employee_Name
1 1 Sam Walton
2 1 Rob Walton
3 1 Jim Walton
4 1 Alice Walton
5 2 Jeff Bezos
6 2 Brian T. Olsavsky
7 3 Steve Jobs
8 3 Tim Cook
The easiest way to envision a multi-dimensional (nested) array is to mimic the looping required to get it: outer loop is the company, inner loop is the employees:
// ignoring database access, this is just pseudo code
$outer = [];
// select id, company_name from company
foreach $companyResult as $companyRow {
// select * from employee where company_id = ? {$companyRow['id']}
$inner= [];
foreach $employee_result as $employeeRow {
$inner[] = $employeeRow; // ie, ['id'=>'1','Company_Id'=>'1','Employee_Name'=>'Sam Walton']
}
$outer[] = $inner;
}
print_r($outer);
// yields ====>
Array
(
[0] => Array
(
[0] => Array
(
[id] => 1
[Company_Id] => 1
[Employee_Name] => Sam Walton
)
[1] => Array
(
[id] => 2
[Company_Id] => 1
[Employee_Name] => Rob Walton
)
[2] => Array
(
[id] => 3
[Company_Id] => 1
[Employee_Name] => Jim Walton
)
[3] => Array
(
[id] => 4
[Company_Id] => 1
[Employee_Name] => Alice Walton
)
)
[1] => Array
(
[0] => Array
(
[id] => 5
[Company_Id] => 2
[Employee_Name] => Jeff Bezos
)
[1] => Array
(
[id] => 6
[Company_Id] => 2
[Employee_Name] => Brian T. Olsavsky
)
)
[2] => Array
(
[0] => Array
(
[id] => 7
[Company_Id] => 3
[Employee_Name] => Steve Jobs
)
[1] => Array
(
[id] => 8
[Company_Id] => 3
[Employee_Name] => Tim Cook
)
)
)
It is also possible to do if you use associative arrays. Consider the flat file that this query produces:
select company.id company_id, company.name company_name,
emp.id employee_id, emp.employee_name
from company
inner join employee on company.id = employee.company_id
-----
company_id company_name employee_id employee_name
1 Walmart 1 Sam Walton
1 Walmart 2 Rob Walton
1 Walmart 3 Jim Walton
1 Walmart 4 Alice Walton
2 Amazon.com 5 Jeff Bezos
2 Amazon.com 6 Brian T. Olsavsky
3 Apple 7 Steve Jobs
3 Apple 8 Tim Cook
Just use the primary IDs as the keys for your arrays:
$employeeList = [];
foreach($result as $row) {
$cid = $row['company_name'];
$eid = $row['employee_name'];
// avoid uninitialized variable
// $employeeList[$row['company_name']] = $employeeList[$row['company_name']] ?? [];
// easier to read version of above
$employeeList[$cid] = $employeeList[$cid] ?? [];
// assign it...
$employeeList[$cid][$eid] = $row;
}
Or, if you simply want each company row to hold an array of employee names,
$employeeList[$cid][] = $row['employee_name'];
The way that I've shown you is useful if you know the company_id and want to find the associated rows:
foreach($employeeList[2] as $amazon_guys) { ... }
But it's not at all useful if you're trying to group by employee, or some other field in the employee table. You'd have to organize the order of your indexes by your desired search order.
In the end, it's almost always better to simply do another query and let the database give you the specific results you want.

php list and select data using join tables

I have this database table structure for posts, categories and post_categories
posts:
| id | title | details
| 1 | test | test details
categories:
| id | name | parent_id
| 1 | cat one | 0
| 2 | cat two | 0
| 3 | cat three | 0
post_categories
| category_id | post_id
| 1 | 1
| 2 | 1
I insert multiple categories using input checkbox for each post in post_categories table. Now in update page(domain.com/admin/posts/1/edit) i need to show categories list and checked input checkbox.can i generate this output using join two table(categories and post_categories) Or I need to separate two query(first from post_category table and second from categories table) like this output?! (my choice is join method so how to generate use join method?)
<input type="checkbox" value="1" checked> cat one
<input type="checkbox" value="2" checked> cat two
<input type="checkbox" value="3"> cat three //unchecked (not in post_categories table)
update:
for list categories query:
$query = $this->db->table('categories')
->select('id, name, parent_id')
->get()
->getResultObject();
data in print_r:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => cat one
[parent_id] => 0
)
[1] => stdClass Object
(
[id] => 2
[name] => cat two
[parent_id] => 0
)
[2] => stdClass Object
(
[id] => 3
[name] => cat three
[parent_id] => 0
)
[3] => stdClass Object
(
[id] => 4
[name] => cat4
[parent_id] => 2
)
[4] => stdClass Object
(
[id] => 5
[name] => cat5
[parent_id] => 0
)
[5] => stdClass Object
(
[id] => 6
[name] => cat6
[parent_id] => 0
)
)
after join:
$query = $this->db->table('categories')
->select('id, name, parent_id')
->join('post_categories', 'post_categories.category_id = id','left outer')
->where('post_categories.post_id', $id)
->get()
->getResultObject();
and data is:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => cat one
[parent_id] => 0
)
[1] => stdClass Object
(
[id] => 4
[name] => cat two
[parent_id] => 2
)
)
result after join is false.
You can do this with one query but for this, you need one extra column in query for checking category is using or not.
SELECT id, name, if(pc.cat_id IS NULL,0,1) as `value` from categories as ct LEFT JOIN post_categories as pc on pc.cat_id = ct.id
demo link
I hope this query will fulfill your requirements.
If you need more detail about this you can visit this StackOverflow thread
MySQL Join and create new column value
You can run below query to get the categories selected:
select post_categories.category_id from posts
left join post_categories on post_categories.post_id=posts.id
left join categories on post_categories.category_id=categories.id;
get these ids to an array and within your category loop check if the ids are in array and make them checked.
quite easy !

Laravel Relation in multiple table

I have 3 tables like below.
Table A
id | val_a
1 | a1
2 | a2
3 | a3
Table B
id | id_a| val_b | id_c
1 | 2 | b1 | 1
2 | 2 | b2 | 3
3 | 3 | b3 | 4
Table C
id | val_c
1 | c1
2 | c2
3 | c3
4 | c4
What is the best way to get data like below :
[
[0] => stdClass Object
(
[id_a] => 1
[val_a] => 'a1'
)
[1] => stdClass Object
(
[id_a] => 2
[val_a] => 'a2'
[table_b_c] => Array
(
[0] => stdClass Object
(
[id_b] => 1
[val_b] => 'b1'
[id_c] => 1
[val_c] => 'c1'
)
[1] => stdClass Object
(
[id_b] => 2
[val_b] => 'b2'
[id_c] => 3
[val_c] => 'c3'
)
)
)
[2] => stdClass Object
(
[id_a] => 3
[val_a] => 'a3'
[table_b] => Array
(
[0] => stdClass Object
(
[id_b] => 3
[val_b] => 'b3'
[id_c] => 4
[val_c] => 'c4'
)
)
)
]
Model for TableA
class TableA extends Model {
public function getTableA($id_a) {
return $this->where('id', $id_a)->with('TableB', 'TableC')->get()->toArray();
}
}
Model for TableB
class TableB extends Model {
public function tableA(){
$this->belongsTo('App\tableA');
}
public function tableC(){
$this->belongsTo('App\tableC');
}
}
Model for TableC
class TableC extends Model {
}
I have tried above relation but it not work for me.
I am using Laravel 5.2. And achieve this by foreach loop. But I don't know what is the best way to do. Can I do this by laravel or Mysql ? Thanks Ahead.
I've setup some data my side and used this documentation to return a nested object.
Your model function names must be labelled correctly, then this will work:
$data = TableA::with(['recordsB.recordC'])->get();
dd($data->toArray());
This means that all TableA records will be fetch, it then adds all the records from table B related to each A record. As long as the function name in the model is recordsB. The dot syntax then adds the nested and related records from table C (for each B record), given the correct function name once again. See "Nested Eager Loading" in the documentation.
The data you're depicting seems it's not for a specific A record. So better to have the eager loading in a controller perhaps. For this reason I removed the id parameter from getTableA function.
In models - model TableA:
class TableA extends Model {
public function getTableA() {
$data = TableA::with(['recordsB.recordC'])->get();
return $data;
}
public function recordsB(){
$this->hasMany('App\TableB');
}
}
Model TableB:
class TableB extends Model {
public function recordA(){
$this->belongsTo('App\TableA');
}
public function recordC(){
$this->belongsTo('App\TableC');
}
}
Model TableC:
class TableC extends Model {
public function recordsB(){
$this->hasMany('App\TableB');
}
}

How to save special array data into Three MySQL table in PHP

I have JSON which need to insert into MySQL table.
What I already did is, convert it to array using:
$json_data = json_decode($geo_json, true);
and get an output of array but I do not know how to inset into second and third MySQL table.
My MySQL Table:
Table 1:
geo_id | user_id | geo_title | geo_description | geo_date |geo_status |geo_action |action_reason | geo_json | remote_ip | map_type |geo_snapshot
I can able to insert into above table easily but problem is in table two and Three listed below.
Table 2:
id | layer_id | map_id | layer_name | user_id | draw_type | latlng | radious
Table 3:
data_id | geo_key | geo_value | map_id | layer_id
Array I am getting:
Array
(
[type] => FeatureCollection
[features] => Array
(
[0] => Array
(
[type] => Feature
[properties] => Array
(
[action] => a
[poi_name] => a
[fac_type] => 17
[ph_number] => a
[hno] => a
[postcode] => a
[mail] => a
[str_nm] => a
[photo] => developer-page.png
[comment] => a
[url] => a
[sub_loc] => a
[employee] => a
)
[geometry] => Array
(
[type] => Point
[coordinates] => Array
(
[0] => 88.434448242188
[1] => 22.510971144638
)
)
)
[1] => Array
(
[type] => Feature
[properties] => Array
(
[action] => b
[poi_name] => b
[fac_type] => 18
[ph_number] => b
[hno] => b
[postcode] => b
[mail] => b
[str_nm] => b
[photo] => 1475131600_developer-page.png
[comment] => b
[url] => b
[sub_loc] => b
[employee] => b
)
[geometry] => Array
(
[type] => Point
[coordinates] => Array
(
[0] => 88.321151733398
[1] => 22.50906814933
)
)
)
)
)
Now problem is to insert above data into two separate tables:
Table 2: This is only require to insert draw_type | latlng from above php array.
Example: draw_ type: point and latlng : coordinates
Table 3:
This is require to insert geo_key | geo_value | map_id | layer_id from above PHP array.
Example:
geo_key : properties [action,poi_name,fac_type,ph_number,hno,postcode,mail,str_nm, photo, comment, url, sub_loc, employee]
geo_value : [properties values ]
map_id :[this will be table 1 insert id]
layer_id : [this can be blank]
Please guide me and show me how to start.
$json_data["features"][$array_index]["geometry"]["type"]
For table2:
foreach($json_data["features"] as $info){
$type = $info["geometry"]["type"];
$latlng_0 = $info["geometry"]["coordinates"][0];
$latlng_1 = $info["geometry"]["coordinates"][1];
// DO INSRET with $type, $latling_0, $latling_1
$sql = "INSERT INTO Table2 (draw_type, latlng0, latlng1) VALUES ('".$type."','".$latlng_0."','".$latlng_1."')";
....
}
For table3:
Is 'map_id' a auto increment key in table1?
You'll need to know map_id first by select * where (conditions)
after successful insert data to table1
And if 'layer_id' can accept blank (null) data, it'll be fine if you don't specific value in INSERT command. Just make sure your table have correct settings.

How to arrange the obtained result's Array given Below, to get a desired result given below?

I Have a query
SELECT classid, COUNT(*) as cnt FROM tbl_name GROUP BY classid
on Table
| id | classid | contextid |
1 1 2
2 1 1
3 2 1
4 1 1
this will yields me the result by the use of an inbuilt library function moodle as
Array
(
[1] => stdClass Object
(
[classid] => 1
[classcnts] => 3
)
[2] => stdClass Object
(
[classid] => 2
[classcnts] => 1
)
)
I need the result in an array in the form of
Array(
[classid]=>[classcnts]
)
i.e
Array(
1=>3,
2=>1
)
So how can i arrange the available array to find the required array.
I am working in PHP
Thanks
try:
foreach($arr as $k){
$new[$k->classid] = $k->classcnts
}

Categories