i have following tables
Author
id | author_name | author_detail | author_bio
books
id | author_id | book_name | book_detail
i want to display data in following way
Author Name ::
Author Detail ::
books :: 1.book1
2.book2
3.book3
4.book4
i have tried following query but didnt worked as per my requirement
select * from authors left join books on author.id=books.author_id
i have tried group concat but it gives books name with coma seperate.so i want to books detail in array
select author.author_name,author.author_detail,author.author_bio,group_concat(books.book_name) eft join books on author.id=books.author_id
i am expexting output like
Array
(
[0] => Array
(
[id] => 1
[name] => Norm
[books] => Array
(
[0] =>Array
(
[id] => 4
[book_name] => great wall
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
[1] =>Array
(
[id] => 6
[book_name] =>new book
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
)
)
[1] => Array
(
[id] => 2
[name] => Norm
[books] => Array
(
[0] =>Array
(
[id] => 2
[book_name] => amazing star
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
[1] =>Array
(
[id] => 3
[book_name] =>way of journy
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
)
)
i have checked this question also
displaying php mysql query result with one to many relationship
Can any one help me how to display data like above ?
thank you
Try this:
SELECT
A.id
A.author_name,
A.author_detail,
A.author_bio,
B.book_name,
B.created_at,
B.updated_at
FROM books AS B
LEFT JOIN author AS A
ON (A.id=B.author_id)
you will get result like this:
id | author_name | author_detail | author_bio | book_name
1 | ari | some detail | some bio | book_ari_1
1 | ari | some detail | some bio | book_ari_2
1 | ari | some detail | some bio | book_ari_3
2 | tester | some detail | some bio | book_tester_1
etc..
to make array as your expecting result you need to restructure your array result. i will asume your result array will be in $result variable
$new_result = array();
foreach ($result as $key => $value) {
if (empty($new_result[$value['id']]))
{
$new_result[$value['id']] = array(
'id' => $value['id'],
'name' => $value['name'],
'books' => array(
array(
'id' => $value['id'],
'book_name' => $value['book_name'],
'created_at' => $value['created_at'],
'updated_at' => $value['updated_at']
),
)
)
}
else
{
$new_result[$value['id']]['id'] = $value['id'];
$new_result[$value['id']]['name'] = $value['name'];
$new_result[$value['id']]['books'][] = array(
'id' => $value['id'],
'book_name' => $value['book_name'],
'created_at' => $value['created_at'],
'updated_at' => $value['updated_at']
);
}
}
the result will look like your expected. but the key number will be formated as id.
to reset key of $new_result as increment number you need to get only value use array_values() function
$new_result = array_values($new_result);
You could do it with your first query...but you'd have to check the author_id inside the record loop and show the author details only whenever the value changed (by comparing it with a value stored in a variable)...otherwise only show the book details.
So your code might (very roughly) look like this:
$query = "select whatever whatever...";
$records = $database->Execute($query);
foreach ($records as $fields) {
if ($fields['id'] != $previous_id) echo "Author ...";
echo "Book whatever whatever ...";
$previous_id = $fields['id'];
}
A more straightforward (although slightly longer) way would be to have a second query: a sub-query. And it would take place inside the loop through the results of the first (outer) query. So your outer query gets the authors and, after you show the author details, you have this separate query for books of the author...and you have a loop-within-the-outer-loop to show the details of each book.
So your code (very roughly) looks something like this:
$query = "select id, author_name, whatever from author";
$author_records = $database->Execute($query);
foreach ($author_records as $fields) {
echo "Author: {$fields['author_name']} whatever <br/>";
$subquery = "select whatever from books where id = whatever";
$book_records = $database->Execute($subquery);
foreach ($book_records as $otherfields) {
echo "Book whatever whatever";
}
}
you can do this in php no need to go in query itself but take both data in separate query i.e. books and author data
Remember i assumed $result as authors data and $result2 as books data
$item=array();
while($row=mysql_fetch_array($result))
{
$id=$row['id'];
$item[$id]['name']=$row['name'];
$item[$id]['id']=$row['id'];
$item[$id]['books']=array();
$temp=array();
while($row1=mysql_fetch_array($result2))
{
if($id==$row1['author_id'])
{
$temp['id']=$row1['id'];
$temp['book_name']=$row1['book_name'];
$temp['created_at']=$row1['created_at'];
$temp['updated_at']=$row1['updated_at'];
array_push($item['id']['books'],$temp);
}
}
}
Now here id is formatted as author's id. To get like array keys you can use array_values($item)
Related
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.
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.
given a very simple table structure thus:
mysql> describe songpart;
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | MUL | NULL | auto_increment |
| partName | text | NO | | NULL | |
+----------+---------+------+-----+---------+----------------+
which results in an array like this in php (when queried)
Array ( [0] => Array ( [id] => 1 [0] => 1 [partName] => Lead Guitar [1] => Lead Guitar )
[1] => Array ( [id] => 2 [0] => 2 [partName] => Bass Guitar [1] => Bass Guitar )
[2] => Array ( [id] => 3 [0] => 3 [partName] => Drums [1] => Drums )
[3] => Array ( [id] => 4 [0] => 4 [partName] => Keyboard [1] => Keyboard ) )
Am I missing some simple trick to turn this into a simple array with id as the key like so:
Array ( [1] => Lead Guitar
[2] => Bass Guitar
[3] => Drums
[4] => Keyboard )
or is it possible to get PDO to deliver an array like this?
TiA
You can simply use the PDO::FETCH_KEY_PAIR is you have only 2 columns in your result.
You can also use the PDO::FETCH_GROUP and PDO::FETCH_ASSOC together if you have more. Example :
$result = $db->query('select * from channels')->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
This will yield an array indexed with the first column containing at each index an array of the result for this key. You can fix this by using array_map('reset', $result) to get your goal.
Example :
$result = array_map('reset', $db->query('select * from channels')->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC));
Try this:
$records = $pdo->query('SELECT id, partName FROM myTable');
$records->setFetchMode(PDO::FETCH_KEY_PAIR);
print_r($records->fetchAll());
For that you need to set only your desired fields in iteration.
$part_name = [];
$records = $pdo->query('SELECT * FROM your_table');
foreach ($records as $row) {
$part_name[$row['id']] = $row['partName'];
}
My Problem
Trying to create similar arrays so I can compare them.
I am creating a distribution list for files, the adding of the distribution list work fine, I list user surname, user forename and user department, these are selected and posted, foreach user I retrieve the users.user_id and store this in a distribution table (under distro_lis)t like so.
distro_id (AI, PK) | distro_list | policy_id
---------------------------------------------
1 | 1 23 21 34 | 13
2 | 10 22 21 34 | 15
3 | 1 27 26 40 | 34
Now I working on the editing of the distribution list, so for a row, lets say row 1, I fetch the distro_list and parse it to get each user ID (from distro_list) using.
$policyID is received in the method argument
$db = $this->dbh->prepare('SELECT distro_list FROM distro WHERE policy_id = :policy_id');
$db->bindParam(':policy_id', $policyID);
$db->execute();
$row = $db->fetch(PDO::FETCH_ASSOC);
$ids = explode(' ',$row);
foreach ($ids as $user) {
$db = $this->dbh->prepare('SELECT user_forename, user_surname, user_dept FROM users WHERE user_id = :user_id ORDER BY user_surname ASC');
$db->bindParam(':user_id', $user);
$db->execute();
$row = $db->fetch(PDO::FETCH_ASSOC);
var_dump($row);
}
the var_dump($row) returns an array of arrays (objects.. not sure of the terminology here) which looks like so (print_r).
Array
(
[user_forename] => fname1
[user_surname] => sname1
[user_dept] => dept1
)
Array
(
[user_forename] => fname2
[user_surname] => sname2
[user_dept] => dept2
)
Array
(
[user_forename] => fname3
[user_surname] => sname3
[user_dept] => dept3
)
the array that I want to compare it to looks like so (print_r).
array
(
[0] => Array
(
[user_forename] => fname1
[user_surname] => sname1
[user_dept] => dept1
)
[1] => Array
(
[user_forename] => fname2
[user_surname] => sname2
[user_dept] => dept2
)
[2] => Array
(
[user_forename] => fname3
[user_surname] => sname3
[user_dept] => dept3
)
)
I understand why the first array looks like that, because im var_dump'ing' after each iteration. How can I get the first array (array of arrays or objects) into a single array so I can compare it to the second array?
Try this
$list_users = array()
foreach ($ids as $user) {
//...
$list_users[] = $row;
}
var_dump($list_users);
Sorry for the vague title, if anyone would like to edit it to reflect more about what I am posting, please do so. Here is the situation. I have 3 tables:
support:
id | contact_id | title | problem | etc
supportlogin:
id | contact_id | login | pass | etc
contact:
id | first_name | last_name | email | etc
I am loading the support bean just fine, and am accessing the contact info:
$support=R::load('support',1);
echo $support->contact->first_name;
I want to echo the supportlogin information similarly:
echo $support->contact->ownSupportlogin->login;
Is this possible, and am I doing it the right way? I have tried the following ways with no success:
echo $support->contact->supportlogin->login;
echo $support->contact->ownSupportlogin->login;
echo $support->contact->ownSupportlogin[0]->login;
EDIT: MORE INFO
I did print_r($support->contact) and was given the data:
RedBean_OODBBean Object
(
[null:RedBean_OODBBean:private] =>
[properties:RedBean_OODBBean:private] => Array
(
[id] => 109
[phone] => 1234580970
[first_name] => Tim
[last_name] => Withers
)
[__info:RedBean_OODBBean:private] => Array
(
[type] => contact
[sys.id] => id
[tainted] =>
)
[beanHelper:RedBean_OODBBean:private] => RedBean_BeanHelperFacade Object
(
)
[fetchType:RedBean_OODBBean:private] =>
)
And then I did print_r($support->contact->ownSupportlogin) and this showed up:
Array
(
[13] => RedBean_OODBBean Object
(
[null:RedBean_OODBBean:private] =>
[properties:RedBean_OODBBean:private] => Array
(
[id] => 13
[link] => fecd4ef67e8c789efa1792f9ee0efff4
[login] =>
[password] =>
[receiveemails] => 1
[contact_id] => 109
[role] => 1
)
[__info:RedBean_OODBBean:private] => Array
(
[type] => supportlogin
[sys.id] => id
[tainted] =>
)
[beanHelper:RedBean_OODBBean:private] => RedBean_BeanHelperFacade Object
(
)
[fetchType:RedBean_OODBBean:private] =>
)
)
I can access it using: echo $support->contact->ownSupportlogin[13]->login;, but doing it dynamically seems to be a problem....
Figured it out, and will leave it up in case anyone else has a similar problem:
This will only work if you have a 1:1 relationship. Redbean populates the ownSupportlogin as an array of all supportlogin rows related to the contact. If one table can have many child tables, then you will need to loop through that array and pull out the data you want. If it is a 1:1 relationship, then you can use PHP's reset() to access the data of the first element in the array:
echo reset($support->contact->ownSupporlogin)->login;