i want to do the following but haven't found how to.
Or i'm not sure if there is a better way / practice, if you can point me that way i will appreciate it.
I have 2 tables on my DB
Table1 : Categories
Table2 : Subcategories
Table2 is associated with table1 by the primary key.
So for 1 row in the table1 i can have multiple associated rows on the table2.
I query and fetch the data on my Table1 like this:
$result = $mysqli->query("SELECT * FROM table1");
$post = array();
while ($row = $result->fetch_object()){
$row->sub = get_subcategories($row['id']); /* this value is added to the array since i want to store in here the associated arrays from the table2 */
$post[] = $row;
}
return $post;
Then i do the following query also on another function for the table2 data based on every id from the table1
function get_subcategories($id){
$result = $mysqli->query("SELECT * FROM table2 where categories_id = '$id'");
$post = array();
while ($row = $result->fetch_object()){
$post[] = $row;
}
return $post;
}
But the result im getting when using var_dump doesn't seem right.
Can i do it? or what am i doing wrong?
Thanks in advance
Use a single JOIN query:
$result = $mysqli->query("SELECT * FROM table1 t1 JOIN table2 t2 ON t2.categories_id = t1.id ORDER BY t1.id");
$posts = array();
while ($row = $result->fetch_object) {
if (!isset($posts[$row->categories_id])) {
$posts[$row->categories_id] = $row;
$posts[$row->categories_id]->sub = array();
}
$posts[$row->categories_id]->sub[] = $row;
}
This will create nested arrays. The first level will be an associative array whose keys are category IDs and values are objects. The objects will have a sub property that is an array of all the subcategories. Both the categories and subcategories are the objects returned by fetch_object, so there will be duplication. But you can just refer to the appropriate object properties for a particular level.
Related
I am working on a report on which all employees and their salary detail will be fetch according to the departments wise. I have successfully fetch the employees by the department using multidimensional array but now I need to fetch the employees_salary_detail on that employees detail multidimensional array. It means first department->emp_detail->salarydetail. I have successfully fetch the first two part but now i am facing issue on fetching the last array in that emp_detail array.
public function getDepartmentReport(){
$employee = $this->db->select('*')
->from('departments')
->where('project_id', $this->session->userdata('client_id'))->get()->result_array();
$data = array();
foreach($employee as $m => $v){
$v['emp_detail'] = $this->db->select('first_name,employee_code,employees_salary.*')
->from('employees')
->join('employees_salary', 'employees_salary.employee_id = employees.id')
->where('employees.department_id',$v['id'])
->where('employees_salary.month', 'Nov')
->get()->result_array();
$data[] = $v;
foreach($v['emp_detail'] as $m => $s){
$s['salary_detail'] = $this->db->select('*')
->from('employees_salary_detail')->where('employees_salary_detail.salary_id', $s['id'])
->get()->result_array();
$data[] = $s;
}
}
return $data;
}
But now it is creating seperate array for showing salary detail not in that emp_detail array.
I don't know where i am making mistake. please help me to fix this issue.
THANK YOU IN ADVANCE FOR HELPING
Use Join Method to join all three tables in the database on the basis of common keys. I can see you have joined two tables same way you can join multiple tables and create a single array of data.
$qry = $this->db->query("SELECT * FROM product_section INNER
JOIN products ON product_section.ps_prid = products.prid INNER
JOIN wishlist ON wishlist.wish_product_id = products.product_id
INNER JOIN customer ON wishlist.wish_user_id = customer.cust_id
INNER JOIN brands ON brands.brand_id = products.product_brand
WHERE customer.cust_id = '$cid' GROUP BY
product_section.ps_prid");
like this above code
I have a database with several tables. I'm able to query IDs from a single table. What I'd like to do is Use those IDs to query another tables IDs, then use these new IDs to query fields from the final table. Here is what I am currently doing:
Here is how I acquire the first set of IDs:
$returnedPost = mysqli_query($con, "SELECT Region_ID FROM Region WHERE RegionName='" . $queryVar . "'");
function resultToArray($result) {
$rows = array();
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
$rows = resultToArray($returnedPost);
//$rows[x]['Region_ID'];//returns Region_ID 1...n
I'd like to use the IDs in $rows to be able to query a new set of IDs from other tables as follows:
$newTbl = mysqli_query($con, "SELECT Location_ID FROM Location WHERE Region_ID=" . $rows[$x]['Region_ID']);
$rows2 = resultToArray($newTbl);
$finalTbl = mysqli_query($con, "SELECT Field1, Field2 FROM Posts WHERE Location_ID=" . $rows2[$x]['Location_ID']);
Can someone please tell me how I can accomplish this? Thanks.
you can use INNER JOIN in one query to get at this data, maybe something like this
SELECT P.Field1,P.Field2
FROM Region R
INNER JOIN Location L ON R.Region_ID = L.Region_ID
INNER JOIN Posts P ON L.Location_ID = P.Location_ID
WHERE R.RegionName = Your_Region_QueryVar
I am trying to inject an array into an object but it's just not working. This is what I am doing:
1) Get a specific Match record from the database
2) Get all the Player records from the database that are associated with that match
3) Add them players to the Match object
Code:
$matchQuery = "SELECT * FROM matches where new = 1 order by date asc limit 1";
$matchResult = mysql_query($matchQuery,$link) or die('Errant query: '.$matchQuery);
/* create one master array of the records */
$matches = array();
if(mysql_num_rows($matchResult)) {
while($match = mysql_fetch_assoc($matchResult)) {
$playersQuery = "SELECT p.* FROM match_players mp
LEFT JOIN players p on p.id = mp.player_id
WHERE mp.match_id = '$match->id'";
$playerResult = mysql_query($playersQuery,$link) or die('Errant query: '.$playersQuery);
$players = array();
if(mysql_num_rows($playerResult)) {
while($player = mysql_fetch_assoc($playerResult)) {
$match->players[] = $player; //<-- This doesn't seem to work
}
}
$matches[] = $match;
}
}
The objects within Match are being spat out, BUT, the Players are not.
$match is an array, the result of the deprecated mysql_fetch_assoc(). So $match->players[] = $player; is not going to work.
If there is no players key in the sql result, you can add it to the array:
$match['players'][] = $player;
Otherwise you would have to use a different key.
Another problem is your query in the loop: You use $match->id and that should be $match['id'] as $match is an array.
By the way, doing sql queries in a loop is never a good idea, you should try to get your results in one query joining the different tables.
$match["players"] = array();
while($player = mysql_fetch_assoc($playerResult)) {
$match["players"][] = $player;
}
I am running a sql query, that pulls the id, catid, name, subof from two tables using inner join.
select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name
Now this results everything i need but I need to loop through the result and do another sql query for the subof value (which is a value, the value being a ID number of the shop_cat). I need to pull the catname of the subof value #, then update the result/array field subof to the name of the cat.
So if the original query gave me a value of 15 for subof, it would do a select catname from shop.cat where id='15' i would take the catname from that query and then update subof = catname for every value in the original result that has a subof value.
EDIT 3/23/13 12:30pm MST: Using more of the code that Opeyemi wrote, to explain more of what I need. I am not sure how else to explain it...
$q = "select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name";
$r = mysql_query();
while(list($shopid, $catid, $name, $catname, $subof) = mysql_fetch_array($r)) {
$getname = mysql_query("select catname from shop_cat where id='$subof'");
$rowname = mysql_fetch_assoc($getname);
//code to update array to change value of $subof to new $rowname['catname']
}
The DB query runs, gets me my values.
I then need to run a loop of some kind, which will loop through every result PHP aquired from the query. This loop will take the subof value (which is a integer ID number) then run a query to get the value catname of that integer value. Then the loop will update the current result and change the subof value from the integer to the catname pulled from the DB in the loop.
I do not need to update the database at anytime, I need to update the result/array from the first query.
What you need to do is to store the resultset in an array and replace within the array.
$q = "select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name";
$r = mysql_query();
$dataset = array();
// Store result in an array
while($assoc = mysql_fetch_assoc($r)) {
$dataset[] = $assoc;
}
// Update array
foreach($dataset as $data) {
$getname = mysql_query("select catname from shop_cat where id='{$data['subof']}'");
$rowname = mysql_fetch_assoc($getname);
// replace data
replace_dataset($data['subof'], $rowname);
}
function replace_dataset($key, $newname) {
global $dataset;
foreach($dataset as $k => $data) {
if ($data['id'] == $key)
$dataset[$k]['subof'] = $newname;
}
}
Are you asking how to do this in PHP or what? If you are looking for how to loop results in PHP it is as simple as this
$q = "select shop.id, shop.catid, shop.name, shop_cat.catname, shop_cat.subof from shop inner join shop_cat on shop.catid = shop_cat.id where shop.active='1' order by shop_cat.catname, shop.name";
$r = mysql_query();
while(list($shopid, $catid, $name, $catname, $subof) = mysql_fetch_array($r)) {
// the values from the query are assigned to the variables
// $shopid, $catid, $name, $catname, $subof in that order already
mysql_query("update shop_cat set subof=catname where id='$subof'");
// My interpretation of your query can be wrong though
// But you should get the idea
}
You can use mysql_fetch_assoc() or mysql_fetch_array() or mysql_fetch_row() functions to fetch the row and can put your looping concept on it.
After that you can use mysql_fetch_field() to fetch field subof and id from it.
and update the database after that
You can check the following links
http://www.php.net/manual/en/function.mysql-fetch-array.php
http://www.php.net/manual/en/function.mysql-fetch-assoc.php
http://www.php.net/manual/en/function.mysql-fetch-field.php
I hope you get some idea.
Please see the data tables and query below ..
Items
Id, Name
1, Item 1
2, Item 2
Categories
Id, Name, Parent ID
1, Furniture , 0
2, Tables, 1
3, Beds, 1
4, Dining Table, 2
5, Bar Table, 2
4, Electronics, 0
5, Home, 4
6, Outdoors, 4
7, Table lamp, 4
ItemCategory
ItemId, CategoryId
1, 2 .. Row1
2, 4 .. Row 2
2, 5 .. Row 3
ItemCategory table stores which items belongs to which category. An item can belong to top level and or sub category. there are about 3 level deep categories, that is, Tob level, sub level, and sub sub level.
Users select all of the categories they want to view and submit and I can query the database by using a sample query below..
SELECT * FROM items i INNER JOIN ItemCategory ic ON
ic.itemId = i.itemId AND ic.itemId IN ('comma separated category ids')
This works fine.
My question is that Is it possible to view all the items under a top level category even though it has not been directly assigned to the item. For example, if users select Furniture above, then it lists all the items belonging to its sub categories (even though the ItemCategory doesn't contain any record for it)??
I'm open to making necessary amendements to the data table or queries, please suggest a solution. Thank you.
Watcher has given a good answer, but I'd alter my approach somewhat to the following, so you have a structured recursive 2-dimensional array with categories as keys and items as values. This makes it very easy to print back to the user when responding to their search requirements.
Here is my approach, which I have tested:
$items = getItemsByCategory($topCategory);
//To print contents
print_r($items);
function getItemsByCategory($sid = 0) {
$list = array();
$sql = "SELECT Id, Name FROM Categories WHERE ParentId = $sid";
$rs = mysql_query($sql);
while ($obj = mysql_fetch_object($rs)) {
//echo $obj->id .", ".$parent." >> ".$obj->name."<br/>";
$list[$obj->name] = getItems($obj->id);
if (hasChildren($obj->id)) {
array_push($list[$obj->name],getItemsByCategory($obj->id));
}
}
return $list;
}
function getItems($cid) {
$list = array();
$sql = "SELECT i.Id, i.Name FROM Items p INNER JOIN ItemCategory ic ON i.id = ic.ItemId WHERE ic.CategoryId = $cid";
$rs = mysql_query($sql);
while ($obj = mysql_fetch_object($rs)) {
$list[] = array($obj->id, $obj->name);
}
return $list;
}
function hasChildren($pid) {
$sql = "SELECT * FROM Categories WHERE ParentId = $pid";
$rs = mysql_query($sql);
if (mysql_num_rows($rs) > 0) {
return true;
} else {
return false;
}
}
Hope this helps.
With recursion, anything is possible:
function fetchItemsByCat($cat, &$results) {
$itemsInCat = query("SELECT Items.Id FROM Items INNER JOIN ItemCategory ON ItemCategory.ItemId = Items.Id WHERE CategoryId = ?", array($cat));
while($row = *_fetch_array($itemsInCat))
array_push($results, $row['Id']);
$subCategories = query("SELECT Id FROM Categories WHERE Parent = ?", array( $cat ));
while($row = *_fetch_array($subCategories))
$results = fetchItemsByCat($row['Id'], $results);
return $results;
}
$startCat = 1; // Furniture
$itemsInCat = fetchItemsByCat($startCat, array());
The function is somewhat pseudo-code. Replace *_fetch_array with whatever Database extension you are using. The query function is however you are querying your database.
Also, this is untested, so you should test for unexpected results due to using an array reference, although I think it's good to go.
After calling the function, $itemsInCat will be an array of integer ids of all of the items/subitems that exist in the given start category. If you wanted to get fancy, you can instead return an array of arrays with each 2nd level array element having an item id as well as that item's assigned category id, item name, etc.
If you use MySQL, you're out of luck short of indexing your tree using typical techniques, which usually means pre-calculating and storing the paths, or using nested sets:
http://en.wikipedia.org/wiki/Nested_set_model
If you can switch to PostgreSQL, you can alternatively use a recursive query:
http://www.postgresql.org/docs/9.0/static/queries-with.html
Evidently, you can also recursively query from your app, but it's a lot less efficient.