PHP: Join two separate mysql queries into the same json data object - php

I'm trying to mesh the below mysql query results into a single json object, but not quite sure how to do it properly.
$id = $_POST['id'];
$sql = "SELECT contracts.po_number, contracts.start_date, contracts.end_date, contracts.description, contracts.taa_required, contracts.account_overdue, jobs.id AS jobs_id, jobs.job_number, companies.id AS companies_id, companies.name AS companies_name
FROM contracts
LEFT JOIN jobs ON contracts.job_id = jobs.id
LEFT JOIN companies ON contracts.company_id = companies.id
WHERE contracts.id = '$id'
ORDER BY contracts.end_date";
$sql2 = "SELECT types_id
FROM contracts_types
WHERE contracts_id = '$id'";
//return data
$sql_result = mysql_query($sql,$connection) or die ("Fail.");
$arr = array();
while($obj = mysql_fetch_object($sql_result)) { $arr[] = $obj; }
echo json_encode($arr); //return json
//plus the selected options
$sql_result2 = mysql_query($sql2,$connection) or die ("Fail.");
$arr2 = array();
while($obj2 = mysql_fetch_object($sql_result2)) { $arr2[] = $obj2; }
echo json_encode($arr2); //return json
Here's the current result:
[{"po_number":"test","start_date":"1261116000","end_date":"1262239200","description":"test","taa_required":"0","account_overdue":"1","jobs_id":null,"job_number":null,"companies_id":"4","companies_name":"Primacore Inc."}][{"types_id":"37"},{"types_id":"4"}]
Notice how the last section [{"types_id":"37"},{"types_id":"4"}] is placed into a separate chunk under root. I'm wanting it to be nested inside the first branch under a name like, "types".
I think my question has more to do with Php array manipulation, but I'm not the best with that.
Thank you for any guidance.

Combine the results into another structure before outputting as JSON. Use array_values to convert the type IDs into an array of type IDs. Also, fix that SQL injection vulnerability. Using PDO, and assuming the error mode is set to PDO::ERRMODE_EXCEPTION:
$id = $_POST['id'];
try {
$contractQuery = $db->prepare("SELECT contracts.po_number, contracts.start_date, contracts.end_date, contracts.description, contracts.taa_required, contracts.account_overdue, jobs.id AS jobs_id, jobs.job_number, companies.id AS companies_id, companies.name AS companies_name
FROM contracts
LEFT JOIN jobs ON contracts.job_id = jobs.id
LEFT JOIN companies ON contracts.company_id = companies.id
WHERE contracts.id = ?
ORDER BY contracts.end_date");
$typesQuery = $db->prepare("SELECT types_id
FROM contracts_types
WHERE contracts_id = ?");
$contractQuery->execute(array($id));
$typesQuery->execute(array($id));
$result = array();
$result['contracts'] = $contractQuery->fetchAll(PDO::FETCH_ASSOC);
$result['types'] = array_values($typesQuery->fetchAll(PDO::FETCH_NUM));
echo json_encode($result); //return json
} catch (PDOException $exc) {
...
}
If $contractQuery returns at most one row, change the fetch lines to:
$result = $contractQuery->fetch(PDO::FETCH_ASSOC);
$result['types'] = array_values($typesQuery->fetchAll(PDO::FETCH_NUM));

It would seem like you'd be better served by consolidating the two queries with a JOIN at the SQL level. However, assuming the two arrays have equal length:
for ($x = 0, $c = count($arr); $x < $c; $x++) {
if (isset($arr2[$x])) {
$arr[$x] += $arr2[$x];
}
}
echo json_encode($arr);
Edit: you would need to change from mysql_fetch_object to mysql_fetch_assoc for this to work properly.

Why are you using 2 distinct arrays ? I would simply add the rows of the 2nd query in $arr instead of $arr2. This way, you end up with a single array containing all rows from the 2 queries.

Related

Return JSON with id in front

How do I pull out the id in front of each JSON return object from my API?
Current:
{
"1516":{
"id":"1516",
"firstname":"Aluno",
"lastname":"Teste",
"email":"teste#gmail.com",
"dlastaccess":"28-10-2016",
"coursename":"Curso Demonstra\u00e7\u00e3o"
}
}
How do I want to leave:
[
{
"id":"1516",
"firstname":"Aluno",
"lastname":"Teste",
"email":"teste#gmail.com",
"dlastaccess":"28-10-2016",
"coursename":"Curso Demonstra\u00e7\u00e3o"
}
]
I'm trying to do this because my checklist-model does not work the way the JSON return comes, so I can not check all the checkboxes.
API:
This does the job:
$json = '{"1516":{"id":"1516","firstname":"Aluno","lastname":"Teste","email":"teste#gmail.com","dlastaccess":"28-10-2016","coursename":"Curso Demonstra\u00e7\u00e3o"}}';
$values = json_decode($json, true);
$values = array_values($values);
echo json_encode($values);
returns:
[{"id":"1516","firstname":"Aluno","lastname":"Teste","email":"teste#gmail.com","dlastaccess":"28-10-2016","coursename":"Curso Demonstra\u00e7\u00e3o"}]
I guess your $result is an array (or object) of this type:
$result[id] = array(sql retrieved);
Because sql returns you a list of results, even if the result is unique. Imagine that your query returned two results, how could you separate them?
Try:
echo json_encode($result[$cursoid])
or
echo json_encode($result->$cursoid)
$cursoid = $_GET['idcurso'];
$sql = 'SELECT
user2.id AS ID,
user2.firstname AS Firstname,
user2.lastname AS Lastname,
user2.email AS Email,
IF (user2.lastaccess = 0,"nunca",
DATE_FORMAT(FROM_UNIXTIME(user2.1astaccess),"%d-96m-W")) AS dLastAccess ,c.fullname AS Coursename
FROM mdl_user_enrolments AS ue
JOIN mdl_enrol AS e ON e.id = ue.enrolid
JOIN mdl_course AS c ON c.id = e.courseid
JOIN mdl_user AS user2 ON user2 .id = ue.userid
WHERE (SELECT timeaccess FROM mdl_user_lastaccess WHERE userid=user2.id AND courseid=c.id) IS NULL and c.id = ?';
$params = array($cursoid);
$result = $DB->get_records_sql($sql, $params);
echo json_encode(array_values($result)); // You can easily access array values without their keys by array_values(array $param) function
Use array_values, default php function
$values = $DB->get_records_sql( $sql, $params );
$result = array_values( $values );
return json_encode($result);

How to return two table values using join query

Here i am using JOIN query, it will working super, after merging two table value I return one table only, I don't know how return both tables values. From this code task tables value is returned, task_employee table value I can't return, I don't know what will do??
$dapartment = $_POST['department'];
$q = mysql_query("SELECT * FROM task_employee te, task t WHERE te.emp_designation='$dapartment' AND te.emp_id = t.t_assign_to");
$data = array();
while($r = mysql_fetch_assoc($q)){
$data[] = $r;
}
$count = sizeof($data);
if($count > 0){
$return=array('status'=>'success','count'=>sizeof($data),'data'=>$data);
echo json_encode($return);
}else{
$return=array('status'=>'not-found','count'=>sizeof($data),'data'=>$data);
echo json_encode($return);
}
The standard way of an inner join is:
SELECT * FROM task_employee te JOIN task t ON te.emp_id = t.t_assign_to WHERE te.emp_designation='$dapartment'

php while loop inside a foreach loop

Here this line $find_cond = str_replace('|',' ',$rem_exp); returns 225 and 245 number.
I want to get the records based on these two id number. But this below code returns the output repeatedly.
How do I properly put the while loop code inside a foreach?
foreach($arr_val as $key => $val)
{
$c_subsubtopic = str_replace('-','_',$subsubtopic);
$rem_exp = $val[$c_subsubtopic];
$find_cond = str_replace('|',' ',$rem_exp);
$sql = "SELECT a.item_id, a.item_name, a.item_url, b.value_url, b.value_name, b.value_id FROM ".TBL_CARSPEC_ITEMS." a, ".TBL_CARSPEC_VALUES." b WHERE a.item_id = b.item_id AND a.item_url = '".$subsubtopic."' AND value_id = '".$find_cond."' AND a.status = '1'";
while($r = mysql_fetch_array(mysql_query($sql)))
{
echo $r['value_name'];
}
}
The problem is that you are redoing the sql query at every iteration of the loop, thus resetting the results internal pointer, so you keep fetching the same array.
$res = mysql_query($sql)
should be on it's own line before the while loop, and then
while($r = msql_fetch_array($res))
This will properly increment through the $res list.
Try this and you are done
As you were getting may get multiple id in the string after replacing it so its better to use IN the where clause
foreach($arr_val as $key => $val)
{
$c_subsubtopic = str_replace('-','_',$subsubtopic);
$rem_exp = $val[$c_subsubtopic];
$find_cond = str_replace('|',',',$rem_exp);
$sql = "SELECT a.item_id, a.item_name, a.item_url, b.value_url, b.value_name, b.value_id FROM ".TBL_CARSPEC_ITEMS." a, ".TBL_CARSPEC_VALUES." b WHERE a.item_id = b.item_id AND a.item_url = '".$subsubtopic."' AND value_id IN('".$find_cond."') AND a.status = '1'";
while($r = mysql_fetch_array(mysql_query($sql)))
{
echo $r['value_name'];
}
}

How to Get another value in another table using a dynamic call

I currently have this query with an array that outputs the variables within using a dynamic input in my form (term), this creates a Dynamic Search with auto complete to fill in all of the details for a product.
$return_arr = array();
$param = $_GET["term"];
$fetch = mysql_query("SELECT * FROM crd_jshopping_products WHERE `name_en-GB` REGEXP '^$param'");
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
//$row_array['category_id'] = $row ['category_id'];
$row_array['product_id'] = $row['product_id'];
$row_array['product_names'] = $row['name_en-GB'];
$row_array['jshop_code_prod'] = $row['product_ean'];
$row_array['_ext_price_html'] = number_format($row['product_price'],2);
if (!empty($row['product_thumb_image']) AND isset($row['product_thumb_image'])){
$row_array['image'] = $row['product_thumb_image'];
}else {
$row_array['image'] = 'noimage.gif';
}
array_push( $return_arr, $row_array);
}
mysql_close($conn);
echo json_encode($return_arr);
Unfortunately I also need to get the category_id which is not in the same table, I have tried to modify my query as such, but to no avail:
$fetch = mysql_query("SELECT * FROM crd_jshopping_products WHERE `name_en-GB` REGEXP '^$param' AND `crd_jshopping_products_to_categories` = `product_id` ");
What step am I missing here ? The product_id's match in both tables?
try this query instead and try to understand what I have written in it:
$fetch = mysql_query("
SELECT
p.*,
c.category_id
FROM
crd_jshopping_products as p
INNER JOIN crd_jshopping_products_to_categories as c
ON p.product_id = c.product_id
WHERE
`p.name_en-GB` REGEXP '^$param'
");
This means:
SELECT:
Give me everything from p and the category_id from c.
FROM:
Do this from rows in the tables crd_jshopping_products (referred to as p) and crd_jshopping_products_to_categories (referred to as c), where the rows match on the count of p.product_id is the same as c.product_id.
WHERE:
Only return the rows where p.name_en-GB REGEXP '^$param'.

Inner Joining 3 queries

I would like to know how I could join these 3 queries together as I'm wanting only one JSON output, I thought INNER JOIN would do this. But don't know how to use this. Can someone guide me onto the right path please?
$json = array();
$following_string = mysqli_real_escape_string($mysqli,$_SESSION['id']);
$call="SELECT * FROM streamdata WHERE streamitem_id < '$lastID' AND streamitem_target=".$following_string." OR streamitem_creator=".$following_string." ORDER BY streamitem_id DESC LIMIT 10";
$chant = mysqli_query($mysqli, $call) or die(mysqli_error($mysqli));
$json['streamdata'] = array();
while ($resultArr = mysqli_fetch_assoc($chant)) {
$json['streamitem_id'] = $resultArr['streamitem_id'];
$json['streamitem_content'] = $resultArr['streamitem_content'];
$json['streamitem_timestamp'] = Agotime($resultArr['streamitem_timestamp']);
$json['streamdata'] = $json;
}
/***** COMMENTS *****/
$check = "SELECT comment_id, comment_datetime, comment_streamitem, comment_poster, comment_content FROM streamdata_comments WHERE comment_poster=".$following_string." ";
$check1 = mysqli_query($mysqli,$check);
$json['streamdata_comments'] = array();
while ($resultArr = mysqli_fetch_assoc($check1)) {
$json['comment_id'] = $resultArr['comment_id'];
$json['comment_content'] = $resultArr['comment_content'];
$json['comment_poster'] = $resultArr['comment_poster'];
$json['comment_datetime'] = Agotime($resultArr['comment_datetime']);
$json['comment_streamitem'] = $resultArr['comment_streamitem'];
$json['streamdata_comments'] = $json;
}
/***** USERS *****/
$check = "SELECT * FROM users WHERE id=".$following_string."";
$check1 = mysqli_query($mysqli,$check);
$json['users'] = array();
while ($resultArr = mysqli_fetch_assoc($check1)) {
$json['username'] = $resultArr['username'];
$json['id'] = $resultArr['id'];
$json['first'] = $resultArr['first'];
$json['middle'] = $resultArr['middle'];
$json['last'] = $resultArr['last'];
$json['users'] = $json;
}
echo json_encode($json);
}
?>
You're fetching unrelated data, so you can't use a join at the SQL level.
But JSON couldn't care less WHAT you feed it, or how. Just build the appropriate PHP-level data structure, e.g.
$data = array();
$data['streamdata'] = array();
... insert data from 'streamdata' query...
$data['streamdata_comments'] = array();
... insert comment data ...
$data['users'] = array();
... insert user data ...
which will give you a 3-way array containing the data from each of your queries. You then pass that entire $data structure to json_encode, and boom - you've got your 3 unrated queries in a single data structure, without every touching an SQL join.
Some previous answers have suggested that you can't join unrelated tables, but these are clearly not unrelated tables. The streamdata and streamdata_comments tables are quite closely related, and the users table maps user ID values in the other tables to names.
At the SQL level, these can be combined easily:
SELECT d.*, c.*, u.*
FROM streamdata AS d
JOIN streamdata_comments AS c ON d.streamitem_ID = c.comment_streamitem
JOIN users AS u ON u.user_id = c.comment_poster
WHERE c.comment_poster = '$following_string'
AND d.streamitem_id < '$lastID'
AND (d.streamitem_target = '$following_string' OR
d.streamitem_creator = '$following_string');
Whether the result makes sense for wrapping into a JSON string is a different matter, on which I can't pontificate. This would give you one record from the comments information for each comment associated with each stream item.
You are fetching unrelated data. Joining data is only usefull when the data to join has a relation.
You can't join apples, cows and monkeys.

Categories