MySQLi query to join over several tables with pure relationship tables - php

so I have this schema as shown in the image.
Now while I've been trying to figure out all day how to do this, I gotta say I haven't become a bit wiser..
What I want to know is if it is possible to get a result like this from one single query?
{
"activitys": [
{
"activity_name": "Bicycling",
"attributes": [
{
"attribute_name": "Time"
},
{
"attribute_name": "city",
"options": [
{
"option_name": "Stockholm"
},
{
"option_name": "Vasteras"
}
]
}
]
},
{
"activity_name":"asdf"
...and so on
}
]
}
And if so, how do I?
Further more, does my schema look stupid or are there some logic to it?
I'm still new at this and I feel that I might have overcomplicated or misinterpreted stuff..
Thanks on advance
Edit: After fiddeling some more I now have managed to get data that are related to each other, as follows:
{
"success": 1,
"activitys": [
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": "47",
"attribute_name": "City",
"option_id": "50",
"option_name": "Stockholm"
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": "47",
"attribute_name": "City",
"option_id": "51",
"option_name": "Vasteras"
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": null,
"attribute_name": "Duration",
"option_id": null,
"option_name": null
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": "49",
"attribute_name": "Bike",
"option_id": "52",
"option_name": "Grandmas old bike"
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": "49",
"attribute_name": "Bike",
"option_id": "53",
"option_name": "My superfast bike"
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": "49",
"attribute_name": "Bike",
"option_id": "54",
"option_name": "My childhood bike"
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": "49",
"attribute_name": "Bike",
"option_id": "55",
"option_name": "Pablos bike"
},
{
"activity_id": "16",
"activity_name": "Bicycling",
"attribute_id": null,
"attribute_name": "Distance",
"option_id": null,
"option_name": null
},
{
"activity_id": "17",
"activity_name": "Running",
"attribute_id": null,
"attribute_name": "Duration",
"option_id": null,
"option_name": null
}
]
}
However as you can see, for some reason the attribute_id for those attributes that don't have any options didn't come along..
I guess when I've sorted that out I just have to come up with some algorithm in order to format my response as expected (as the JSON string in my original post), since that seems impossible to achieve with the rows that mysqli returns.
Here's my code:
if (isset($_POST['get_activitys'])) {
$records = array();
$sql = "SELECT *
FROM activities a
LEFT JOIN activity_attributes aa ON a.activity_id = aa.activity_id
LEFT JOIN attributes at ON aa.attribute_id = at.attribute_id
LEFT JOIN attributes_options ao ON at.attribute_id = ao.attribute_id
LEFT JOIN options o ON ao.option_id = o.option_id";
if($results = $conn->query($sql)) {
if ($results->num_rows) {
while ($row = $results->fetch_object()) {
$records[] = $row;
}
$results->free();
if (!count($records)) {
$response['success'] = 0;
$response['message'] = "Hittade inga aktiviteter";
die(json_encode($response));
} else {
$response['success'] = 1;
$response['activitys'] = array();
foreach ($records as $r) {
array_push($response['activitys'], $r);
}
// Testing
echo "<pre>";
echo json_encode($response, JSON_PRETTY_PRINT);
echo "</pre>";
die();
die(json_encode($response));
}
} else {
$response['success'] = 0;
$response['message'] = "Hittade inga aktiviteter";
die(json_encode($response));
}
} else {
$response['success'] = 0;
$response['message'] = "Database query failed: (" . $conn->errno . ") " . $conn->error;
die(json_encode($response));
}
}

No problem with your query. You need to structure the query result in nested arrays. Here's the untested code.
if (isset($_POST['get_activitys'])) {
$records = array();
$activity_names = array();
$attribute_names = array();
$sql = "SELECT *
FROM activities a
LEFT JOIN activity_attributes aa ON a.activity_id = aa.activity_id
LEFT JOIN attributes at ON aa.attribute_id = at.attribute_id
LEFT JOIN attributes_options ao ON at.attribute_id = ao.attribute_id
LEFT JOIN options o ON ao.option_id = o.option_id";
if($results = $conn->query($sql)) {
if ($results->num_rows) {
while ($row = $results->fetch_object()) {
$activity_names[$row->activity_id] = $row->activity_name;
$attribute_names[$row->attribute_id] = $row->attribute_name;
$records[$row->activity_id][$row->attribute_id][$row->option_id] = $row->option_name;
}
$results->free();
if (!count($records)) {
$response['success'] = 0;
$response['message'] = "Hittade inga aktiviteter";
die(json_encode($response));
} else {
$response['success'] = 1;
$response['activitys'] = array();
foreach ($records as $activity_id => $activity) {
$activity_obj = array('activity_name' => $activity_names[$activity_id], 'attributes' => array());
foreach ($activity as $attribute_id => $attributes) {
$attribute_obj = array('attribute_name' => attribute_names[$attribute_id], 'options' => array());
foreach ($attributes as $option_id => $option_name) {
$option_obj = array('option_name' => $option_name);
$attribute_obj['options'][] = $option_obj;
}
if (!count($attribute_obj['options'])) {
unset($attribute_obj['options']);
}
$activity_obj['attributes'][] = $attribute_obj;
}
if (!count($activity_obj['attributes'])) {
unset($activity_obj['attributes']);
}
$response['activitys'][] = $activity_obj;
}
// Testing
echo "<pre>";
echo json_encode($response, JSON_PRETTY_PRINT);
echo "</pre>";
die();
die(json_encode($response));
}
} else {
$response['success'] = 0;
$response['message'] = "Hittade inga aktiviteter";
die(json_encode($response));
}
} else {
$response['success'] = 0;
$response['message'] = "Database query failed: (" . $conn->errno . ") " . $conn->error;
die(json_encode($response));
}
}

Related

Compare variable of two different array?

Here i want compare two array.
I have two tables one is CATEGORY and second is USER(in which selected multiple category is stored in this format , , , ).
but when the USER want to update their category at that time the earlier selected category should return checked 1 and which is not selected should return checked 0 and here is my code.
case 'cat':
$sql="SELECT category from nesbaty_user where user_id='".$user_id."'";
$qry_res=mysqli_query($con,$sql);
$response1 = array();
while ($array = mysqli_fetch_array($qry_res))
{
foreach (explode(',', $array['category']) as $cat)
{
$response1[]=array('category' => $cat);
$response['Selected_category'] = $response1;
}
}
$qry="SELECT cat_id,category,image_url FROM nesbaty_category";
$qry_res=mysqli_query($con,$qry);
$jsonData = array();
while ($array = mysqli_fetch_assoc($qry_res))
{
$jsonData[] = $array;
$response['category'] = $jsonData;
}
echo json_encode($response);
//echo json_encode(array('data1' =>$response1));
//
mysqli_close($con);
break;
and here is my fetched array from the database.
{
"Selected_category": [
{
"category": "5"
},
{
"category": "6"
},
{
"category": "9"
}
],
"category": [
{
"cat_id": "1",
"category": "Drug",
"image_url": "1.jpg"
},
{
"cat_id": "2",
"category": "Bars",
"image_url": "2.jpg"
},
{
"cat_id": "3",
"category": "Bars",
"image_url": "2.jpg"
},
{
"cat_id": "4",
"category": "Hair Saloon",
"image_url": "2.jpg"
}
]
}
This is for handle this same structure as You provided.
<?php
$response = [];
$sql = "SELECT category from nesbaty_user where user_id='".$user_id."'";
$qry_res = mysqli_query($con, $sql);
$selectedCategories = mysqli_fetch_array($qry_res);
$selectedCategories = explode(',', $selectedCategories['category']);
$qry = "SELECT cat_id,category,image_url FROM nesbaty_category";
$qry_res = mysqli_query($con, $qry);
while ($categories = mysqli_fetch_assoc($qry_res)) {
$categories['checked'] = (int)\in_array($categories['cat_id'], $selectedCategories);
$response[] = $categories;
}
echo json_encode($response);
mysqli_close($con);
If any error writes a comment, I'll fix it.

Convert to JSON array which contain data in 3 tables

Hi am new to this topic and I really need a help from you who really know about this.
Below image shows my db design and query with results.
Following code is that I've tried so far.
<?php
include_once './DbConnect.php';
$db = new DbConnect();
$response = array();
$response["content_info"] = array();
$query = "SELECT Aid, AName, Bid, BName, Cid, CName, Content FROM A, B, C WHERE fk_Aid = Aid AND fk_Bid = Bid";
$result = mysqli_query($db->getConnection(),$query);
while($row = mysqli_fetch_array($result)){
$tmp = array();
$tmp["Aid"] = $row["Aid"];
$tmp["AName"] = $row["AName"];
$tmp["Bid"] = $row["Bid"];
$tmp["BName"] = $row["BName"];
$tmp["Cid"] = $row["Cid"];
$tmp["CName"] = $row["CName"];
$tmp["Content"] = $row["Content"];
// push info to final json array
array_push($response["content_info"], $tmp);
}
header('Content-Type: application/json');
echo json_encode($response);
?>
But it returns following JSON Object:
{
"content_info": [
{
"Aid": "A1",
"AName": "AName1",
"Bid": "B1",
"BName": "BName1",
"Cid": "C1",
"CName": "CName1",
"Content": "aaaaaaa"
},
{
"Aid": "A1",
"AName": "AName1",
"Bid": "B1",
"BName": "BName1",
"Cid": "C2",
"CName": "CName2",
"Content": "abdsdsfdsf"
},
{
"Aid": "A1",
"AName": "AName1",
"Bid": "B2",
"BName": "BName2",
"Cid": "C3",
"CName": "CName3",
"Content": "dfefeeefeee"
},
{
"Aid": "A1",
"AName": "AName1",
"Bid": "B2",
"BName": "BName2",
"Cid": "C4",
"CName": "CName4",
"Content": "fdsfdfdsf"
},
{
"Aid": "A2",
"AName": "AName2",
"Bid": "B3",
"BName": "BName3",
"Cid": "C5",
"CName": "CName5",
"Content": "fsdfsfsfddf"
}
]
}
But This is not the JSON object that I am expected. Following structure is the that I wanted
{
"content_info": [
{
"Aid": "A1",
"AName": "AName1",
"B": [
{
"Bid": "B1",
"BName": "BName1",
"C": [
{
"Cid": "C1",
"CName": "CName1",
"Content": "aaaaaaa"
},
{
"Cid": "C2",
"CName": "CName2",
"Content": "abdsdsfdsf"
}
]
},
{
"Bid": "B2",
"BName": "BName2",
"C": [
{
"Cid": "C3",
"CName": "CName3",
"Content": "dfefeeefeee"
},
{
"Cid": "C4",
"CName": "CName4",
"Content": "fdsfdfdsf"
}
]
}
]
},
{
"Aid": "A2",
"AName": "AName2",
"B": [
{
"Bid": "B3",
"BName": "BName3",
"C": [
{
"Cid": "C5",
"CName": "CName5",
"Content": "fsdfsfsfddf"
}
]
}
]
Please If someone knows could you please tell me what should I need to edit.
Thank You anyone who try for this.
while($row = mysqli_fetch_array($result)){
$tmp = array();
$tmp["Aid"] = $row["Aid"];
$tmp["AName"] = $row["AName"];
$tmp["B"] = array();
$query1 = "select * from B where fk_Aid= ".$row["Aid"];
$result1 = mysqli_query($db->getConnection(),$query1);
if($result1){
while($row1 = mysqli_fetch_array($result1)){
$tmp1 = array();
$tmp1["Bid"] = $row1["Bid"];
$tmp1["BName"] = $row1["BName"];
$tmp1["C"] = array();
$query2 = "select * from C where fk_Bid = ".$row1["Bid"];
$result2 = mysqli_query($db->getConnection(),$query2);
if($result2){
while($row2 = mysqli_fetch_array($result2)){
$tmp2 = array();
$tmp2["Cid"] = $row2["Cid"];
$tmp2["CName"] = $row2["CName"];
$tmp2["Content"] = $row2["Content"];
array_push($tmp1["C"], $tmp2);
}
}
array_push($tmp["B"], $tmp1);
}
}
array_push($response["content_info"], $tmp);
}
Set this to echo json_encode($response,true) for an associative array

How to merge MySQL query result with JSON format

Hi i am trying to merge output of MySQL result in JSON format but i confused how i can do this so guys i need your helps please tell me how i can do this work thank you.
SQL:
$result = $db->sql_query("SELECT a.*,i.member_id,i.members_seo_name
FROM ".TBL_IPB_USER." i
LEFT JOIN ".TBL_IPB_LA." a
ON a.member_id=i.member_id
WHERE i.".$column." = '".$val."' AND a.game = '".$game."'");
while( $dbarray = $db->sql_fetchrow($result) ){
$arr[] = $dbarray;
}
return ($arr);
The normal result and output with JSON format for my query is:
{
"status": 200,
"result": [
{
"member_id": "1",
"member_name": "maxdom",
"ip_address": "177.68.246.162",
"session_onlineplay": "1",
"sid": "IR63374a32d1424b9288c5f2a5ce161d",
"xuid": "0110000100000001",
"serialnumber": "9923806a06b7f700a6ef607099cb71c6",
"game": "PlusMW3",
"members_seo_name": "maxdom"
},
{
"member_id": "1",
"member_name": "maxdom",
"ip_address": "81.254.186.210",
"session_onlineplay": "1",
"sid": "IR3cd62da2f143e7b5c8f652d32ed314",
"xuid": "0110000100000001",
"serialnumber": "978e2b2668ec26e77c40c760f89c7b31",
"game": "PlusMW3",
"members_seo_name": "maxdom"
}
],
"handle": "checkUSER"
}
But i want to merge output and result like this one:
{
"status": 200,
"result": [
{
"member_id": "1",
"member_name": "maxdom",
"ip_address": [
"177.68.246.162",
"81.254.186.210"
],
"session_onlineplay": "1",
"sid": [
"IR63374a32d1424b9288c5f2a5ce161d",
"IR3cd62da2f143e7b5c8f652d32ed314"
],
"xuid": "0110000100000001",
"serialnumber": [
"9923806a06b7f700a6ef607099cb71c6",
"978e2b2668ec26e77c40c760f89c7b31"
],
"game": "PlusMW3",
"members_seo_name": "maxdom"
}
],
"handle": "checkUSER"
}
you better use php for your parser, prevent high load for database, this is sample code
$result = $db->sql_query("SELECT a.*,i.member_id,i.members_seo_name
FROM ".TBL_IPB_USER." i
LEFT JOIN ".TBL_IPB_LA." a
ON a.member_id=i.member_id
WHERE i.".$column." = '".$val."' AND a.game = '".$game."'");
$arr = array();
while( $dbarray = $db->sql_fetchrow($result) ){
$item = $dbarray;
$item['ip_address'] = array($item['ip_address']);
$item['sid'] = array($item['sid']);
$item['serialnumber'] = array($item['serialnumber']);
$index = $dbarray['member_id'];
if(isset($arr[$index]))
{
$arr[$index]['ip_address'] = array_merge($arr[$index]['ip_address'], $item['ip_address'];
$arr[$index]['sid'] = array_merge($arr[$index]['sid'], $item['sid'];
$arr[$index]['serialnumber'] = array_merge($arr[$index]['serialnumber'], $item['serialnumber']);
} else {
$arr[$index] = $item;
}
}
return array_values($arr);

How to combine multiple SQL queries into one to output as JSON in PHP code?

I currently have the following table set up:
StartTime EndTime Performer Event Day Location
-----------------------------------------------------
1:00pm 2:00pm Test Test 0 1
11:00pm 12:00am Test Test 0 0
2:00pm 2:30pm Test Test 1 0
11:00pm 12:00am Test Test 2 1
The JSON output looks something like this:
{
"day0": {
"item1": {
"StartTime": "1:00pm",
"EndTime": "2:00pm",
"Performer": "Test",
"Event": "Test",
"Location": 1
},
"item2": {
"StartTime": "11:00pm",
"EndTime": "12:00am",
"Performer": "Test",
"Event": "Test",
"Location": 0
}
},
"day1": {
"item1": {
"StartTime": "2:00pm",
"EndTime": "2:30pm",
"Performer": "Test",
"Event": "Test",
"Location": 0
}
},
"day2": {
"item1": {
"StartTime": "11:00pm",
"EndTime": "12:00am",
"Performer": "Test",
"Event": "Test",
"Location": 1
}
}
}
Since I'm still learning PHP, I wrote some sloppy code by making 3 queries to the database, each time selecting all data where the day was 1, 2, and 3.
Here's an example of code for fetching data for day=0, which is repeated for day=1 and day=2:
echo '{ "day0" : {';
$sql = "select * from table WHERE day = 0";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
$jsonData = array();
$rowCount = $result->num_rows;
$index = 1;
while($row =mysqli_fetch_assoc($result))
{
echo '"item'.$index.'":';
echo json_encode(array("StartTime" => $row['StartTime'], "EndTime" => $row['EndTime'], "Performer" => $row['Performer'], "Event" => $row['Event'], "Location" => intval($row['Location'])));
if ($rowCount != $index)
{
echo ',';
}
++$index;
}
echo ' }';
// Repeated code for day=1
// Repeated code for day=2
echo ' }';
I feel as though this can be achieved with just one query, but being that I'm new, I'm not sure how to implement it.
I started to do something like this:
$sql = "select * from table";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
$jsonData = array();
$numOfRows = $result->num_rows;
$count = 1;
while($row = mysqli_fetch_assoc($result))
{
$outerIndex = 'day'.$row['day'];
if ($row['day'] == '1')
{
// Do something, not sure
}
if ( !isset( $jsonData[$outerIndex] ) )
{
$innerIndex = 'item'.$count.'';
$jsonData[$outerIndex][$innerIndex] = $row;
}
++$count;
}
echo json_encode($jsonData);
However, I just got stuck, and not really sure how to approach it further.
SQL:
$sql = "SELECT * FROM table ORDER BY Day";
Further down on code:
$result_object = [];
$item = 1;
while ($row = $result->fetch_assoc()) {
if(isset($result_object['day'.$row['Day']]))
{
$result_object['day'.$row['Day']]['item'.$item] = $row;
$item++;
}
else
{
$result_object['day'.$row['Day']]['item1'] = $row;
$item = 2;
}
}
You can then output it with:
echo json_encode($result_object, JSON_PRETTY_PRINT); //JSON_PRETTTY_PRINT is not necessary...
You may disagree with me, but I don't think indexing items with item0, item1 and so on.... or day0, day1 ... is a GOOD idea. I personally prefer that the looping through the result would be:
while ($row = $result->fetch_assoc()) {
if(isset($result_object[$row['Day']]))
{
$result_object[$row['Day']]->items[] = $row;
}
else
{
$result_object[$row['Day']] = (object)['day'=>$row['Day'], 'items'=>[$row]];
}
}
In this case, the result would be an array of objects. ie:
[
{
"day": "0",
"items": [
{
"StartTime": "07:23:56",
"EndTime": "17:24:04",
"Performer": "Performer1",
"Event": "Event1",
"Day": "0",
"Location": "1"
},
{
"StartTime": "09:24:30",
"EndTime": "01:04:37",
"Performer": "Performer2",
"Event": "Event2",
"Day": "0",
"Location": "1"
}
]
},
{
"day": "1",
"items": [
{
"StartTime": "10:25:22",
"EndTime": "11:25:29",
"Performer": "Performer2",
"Event": "Event3",
"Day": "1",
"Location": "2"
}
]
},
{
"day": "2",
"items": [
{
"StartTime": "12:26:08",
"EndTime": "13:26:12",
"Performer": "Performer3",
"Event": "Event4",
"Day": "2",
"Location": "1"
}
]
}
]
The reason: you can easily iterate through each values(an array) in whatever language you're going to use.

Merge results of single JSON output with PHP

I have a JSON array as per below:
{
"aaData": [
{
"Date_time": "23",
"traffic": "22",
"direction": "sent"
},
{
"Date_time": "24",
"traffic": "55",
"direction": "sent"
},
{
"Date_time": "25",
"traffic": "60",
"direction": "sent"
},
{
"Date_time": "26",
"traffic": "43",
"direction": "sent"
},
{
"Date_time": "27",
"traffic": "50",
"direction": "sent"
},
{
"Date_time": "23",
"traffic": "50",
"direction": "received"
},
{
"Date_time": "24",
"traffic": "42",
"direction": "received"
},
{
"Date_time": "25",
"traffic": "52",
"direction": "received"
},
{
"Date_time": "26",
"traffic": "47",
"direction": "received"
},
{
"Date_time": "27",
"traffic": "36",
"direction": "received"
}
]
}
What I'd like to do with it is combine all the results with the same date into a single entry - so for date_time 23 I want it to appear like this
"Date_time": "23",
"traffic-sent": "22",
"traffic-received": "50"
I'd like to do this with PHP if possible? The data is coming from two separate mySQL queries, coming from to different mySQL databases. I've tried combining the output of the query to do what I need (tried Joins and Unions) but can't get past the separation of the results as per my first example.
The part of the SQL query creating the JSON looks like this:
while($row = mysqli_fetch_assoc($result)) {
$model[$i]['Date_time'] = $row['the_day'];
$model[$i]['traffic'] = $row['traffic'];
$model[$i]['direction'] = $row['TABLE_NAME'];
$i++;
}
And the SQL looks like this:
(SELECT
DAY(`Time`) AS the_day,
count(accounts.accName) AS traffic,
"sent" AS TABLE_NAME
FROM
bss.ss_sent LEFT JOIN bss.accounts ON ss_sent.Customer = accounts.accName
WHERE
YEARWEEK(`Time`) = YEARWEEK(CURRENT_DATE)
AND
Customer != " "
AND
accShortName = "QRR"
GROUP BY
the_day)
UNION
(SELECT
DAY(Date_time) AS the_day,
count(AS_Task) AS traffic,
"received" AS TABLE_NAME
FROM
im_stats.as_counter
WHERE
AS_Task = "QRR3 Incoming"
AND
YEARWEEK(Date_time) = YEARWEEK(CURRENT_DATE)
GROUP BY
the_day
Order by the_day)
IF anyone can advise of a way to combine the results I'd very much appreciate it.
UPDATE:
This is how I've entered Populus's code:
$i = 0;
while($row = mysqli_fetch_assoc($result)) {
$model[$i]['Date_time'] = $row['the_day'];
$model[$i]['traffic'] = $row['traffic'];
$model[$i]['direction'] = $row['TABLE_NAME'];
$i++;
}
$combined = array();
foreach ($model as $val) {
$date_time = $val['Date_time'];
if (!isset($combined[$date_time)) {
$combined[$date_time] = array(
'Date_time' => $date_time,
'traffic_sent' => 0,
'traffic_received' => 0,
);
}
if ('received' == $val['direction']) {
$combined[$date_time]['traffic_received'] += $val['traffic'];
} else {
$combined[$date_time]['traffic_sent'] += $val['traffic'];
}
}
header('Content-type: application/json');
print json_encode(array('aaData' => $combined), JSON_PRETTY_PRINT);
This could probably be done using SQL (which you haven't provided), but if you really want PHP:
$combined = array();
foreach ($model as $val) {
$date_time = $val['Date_time'];
if (!isset($combined[$date_time])) {
$combined[$date_time] = array(
'Date_time' => $date_time,
'traffic_sent' => 0,
'traffic_received' => 0,
);
}
if ('received' == $val['direction']) {
$combined[$date_time]['traffic_received'] += $val['traffic'];
} else {
$combined[$date_time]['traffic_sent'] += $val['traffic'];
}
}
Your desired array is now in $combined. If you don't want the keys, you can remove it:
$result = array_values($combined);
Try it this way:
while($row = mysqli_fetch_assoc($result)) {
if ($row['direction'] == 'sent')
$dt[$row['Date_time']]['traffic-sent'] += $row['traffic'];
elseif ($row['direction'] == 'recieved')
$dt[$row['Date_time']]['traffic-recieved'] += $row['traffic'];
}
foreach ($dt as $date) {
echo "Date_time: " . key($date) . ",<br/>" .
"traffic_sent: " . $date['traffic-sent'] . ",<br/>" .
"traffic-recieved: " . $date['traffic-recieved'] . "<br/><br/>";
}

Categories