how to make array of array by looping result from a query - php

I have a survey about games, and I have one table for the games data, and another for people's answers.
I want to output an array in Json format for answers with each of the 3 favorite games name and their year in an array of array.
expected output
[
{
"id": "1",
"username": "userX",
"g1": {"name": "game1", "year": "1991"},
"g2": {"name": "game2", "year": "1992"},
"g3": {"name": "game3", "year": "1993"},
}
]
what i've tried
$sql = "SELECT * FROM tbAnswers AS answer INNER JOIN tbgames AS game ON answer.g1 = game.id";
try {
$db = new db();
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->execute();
$answer = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
if(empty($answer)) {
$response->getBody()->write
('
{
"error":
{
"status":"400",
"message":"Invalid Request"
}
}');
} else {
$response->getBody()->write(json_encode($answer));
}
} catch(PDOException $e) {
$response->getBody()->write
('
{
"error":
{
"message":'. $e->getMessage() .'
}
}');
}
the current output
[
{
"id": "1",
"username": "userX",
"name": "game1",
"year": "1991"
}
]
I think i should do a foreach somewhere in else to go through each game and echo the result of it based on the id from answers, but i am not sure how to apply it
where to place to foreach
how to select and get the results based on each game id
how to do it in json format
i'm sure it's not how i am doing it, this is how i am trying to echo the data in else
echo"[";
echo"\n{";
echo"\n";
echo '"id:"'.' "'.$answer[0]->id.'",';
echo"\n";
echo"}\n";
echo"]";
here are my tables structure
tbGames
id , name , year
1 , 'game1' , '1991'
2 , 'game2' , '1992'
3 , 'game3' , '1993'
4 , 'game4' , '1994'
tbAnswers
id , name , g1 , g2 , g3
1 , userX , 1 , 2 , 3
2 , userY , 3 , 1 , 4
3 , userZ , 1 , 1 , 2
4 , userW , 2 , 3 , 4

Using this query:
$sql = "SELECT answer.id a_id, answer.name a_name, game1.id g1_id, game1.name g1_name, game1.year g1_year, game2.id g2_id, game2.name g2_name, game2.year g2_year, game3.id g3_id, game3.name g3_name, game3.year g3_year FROM tbAnswers AS answer INNER JOIN tbgames AS game1 ON answer.g1 = game1.id INNER JOIN tbgames AS game2 ON answer.g2 = game2.id INNER JOIN tbgames AS game3 ON answer.g3 = game3.id";
you should change your else statement content to:
} else {
foreach($answer as $value) {
$array_resp[]=[
'id' => $value->a_id,
'username' => $value->a_name,
'g1' => ['name'=>$value->g1_name, 'year'=>$value->g1_year],
'g2' => ['name'=>$value->g2_name, 'year'=>$value->g2_year],
'g3' => ['name'=>$value->g3_name, 'year'=>$value->g3_year],
];
}
$response->getBody()->write(json_encode($array_resp));
}

Related

How to collect data from two related tables

I am trying to get data from 2 different tables: users and comments.
I want to return comment data and user data depending on the commentsenderid .
<?php
$commentpostid = $_POST['commentpostid'];
$sql = "SELECT * FROM comments where commentpostid = '{$commentpostid}'";
$sqll = mysqli_query($db, $sql); // $db->query() is also accepted.
$result = mysqli_fetch_all($sqll, MYSQLI_ASSOC);
echo json_encode($result);
Result:
[
{
"commentid": "93",
"comment": "naber kankam Benin",
"commentpostid": "1006",
"commentsenderid": "12"
},
{
"commentid": "95",
"comment": "kankam selam!",
"commentpostid": "1006",
"commentsenderid": "3135"
}
]
Should be:
[
{
"commentid": "93",
"comment": "naber kankam Benin",
"commentpostid": "1006",
"commentsenderid": "12",
"username": "denemeuser",
"userbolum": "denemebolum",
"useryas": "useryasdeneme"
},
{
"commentid": "95",
"comment": "kankam selam!",
"commentpostid": "1006",
"commentsenderid": "3135",
"username": "denemeuser",
"userbolum": "denemebolum",
"useryas": "useryasdeneme"
}
]
[]
[]
You select all comments, join them with users whose id matches the id of the authors of comments, you select only those whose post matches the value you are looking for.
SELECT c.*, u.username, u.userbolum, u.useryas
FROM comments c
JOIN users u ON c.commentsenderid = u.userid
WHERE commentpostid = ?

Removing String from date comming from Oracle12c db

So i need a list of dates comming from database for my app. The thing is i just need the time not date but im unable to remove its string.
ive used this in my other tables but for some reason its not working with this api im using php.
substr($row['DATEFROMTABLE'], 9 , strlen(($row["DATEFROMTABLE"]))-0)
SELECT TO_CHAR( VISIT_DATE, 'DD-MON-YY HH24:MI:SS') AS DATEFROMTABLE
FROM tablename t
LEFT JOIN anothertable d ON t.column=d.column
WHERE t.anothercolumn IS NULL AND t.somedate >= TO_DATE('23-JUL-2019 00:00:00', 'DD-MON-YYYY HH24:MI:SS')
AND t.somedate <= TO_DATE('23-JUL-2019 23:59:59', 'DD-MON-YYYY HH24:MI:SS') AND t.column='somedata here'
ORDER BY VISIT_DATE
$stmt = $conn->prepare($query);
$stmt->execute();
$row=$stmt->fetchAll(PDO::FETCH_ASSOC);
$products = array();
$newarr=count($row);
for($k=0;$k<$newarr;$k++)
{
substr($row[$k], 2 , strlen($row[$k])-8);
array_push($products,$row[$k]);
}
echo json_encode($products);
[
{
"DATEFROMTABLE": "23-JUL-19 11:30:00"
},
{
"DATEFROMTABLE": "23-JUL-19 11:45:00"
},
{
"DATEFROMTABLE": "23-JUL-19 12:00:00"
},
{
"DATEFROMTABLE": "23-JUL-19 12:15:00"
},
{
"DATEFROMTABLE": "23-JUL-19 12:30:00"
},
{
"DATEFROMTABLE": "23-JUL-19 12:45:00"
}
]
i need to remove date from this result
this is the result i get in postman
You can do it by editing your SQL like the following:
SELECT TO_CHAR( VISIT_DATE, 'HH24:MI:SS') AS DATEFROMTABLE
...

Select inside a select query MYSQL

Hello! I have a query that needs to output screens data.
Each screens has 4 booths to be shown. I need a query with one result (because I just have one screen) And has 4 booths in it (coz I assigned 4 booths)
Here's my query:
$result = DB::select("
SELECT
`A`.`scr_name`,
`A`.`mission_id`,
`B`.`booth_id`,
`E`.`name`
FROM `tbl_screen` `A`
LEFT JOIN
`tbl_screen_booths` `B`
ON `B`.`screen_id` = `A`.`id`
LEFT JOIN
`tbl_service_booths` `C`
ON `B`.`booth_id` = `C`.`id`
LEFT JOIN
`tbl_missions_services` `D`
ON `C`.`mission_services_id` = `D`.`id`
LEFT JOIN
`tbl_services` `E`
ON `D`.`service_id` = `E`.`id`
WHERE `A`.`mission_id` = $mission_id
GROUP BY
`B`.`booth_id`;
");
return $result;
I want something like this:
"scr_name": "Test Screen",
"mission_id": 2,
"name": "booth1", //index[0]
"name": "booth2", //index[1]
"name": "booth3", //index[2]
"name": "booth4" //index[4]
My query returns something like this:
[
{
"scr_name": "Test Screen",
"mission_id": 2,
"booth_id": 7,
"name": "booth1"
},
{
"scr_name": "Test Screen",
"mission_id": 2,
"booth_id": 9,
"name": "booth2"
},
{
"scr_name": "Test Screen",
"mission_id": 2,
"booth_id": 10,
"name": "booth3"
},
{
"scr_name": "Test Screen",
"mission_id": 2,
"booth_id": 11,
"name": "booth4"
}
]
the result is okay.. just need a little iterate to get the value..
$data['scr_name'] = $result[0]->scr_name;
$data['mission_id'] = $result[0]-> mission_id;
foreach($result as $index => $item) {
$data['name'.($index+1)] => $item->name;
}
result:
"scr_name": "Test Screen",
"mission_id": 2,
"name1": "booth1", //index[0]
"name2": "booth2", //index[1]
"name3": "booth3", //index[2]
"name4": "booth4" //index[4]
array key cant have same key name

Placing a json array inside the first array?

How would I make the $query_ppimage results a sub array from the first users query? At the moment, the output is outputting a user, then a profile image, under the user, rather than inside the users array. Therefore they aren't linked.
How would I do such a thing?
Here is my code:
$query_user = "SELECT *,'user' AS type FROM users WHERE username LIKE '".$query."' OR firstname LIKE '".$query."' OR lastname LIKE '".$query."'";
$quser = $conn->query($query_user);
$rows = array();
while($user = mysqli_fetch_assoc($quser)) {
$query_ppimage = "SELECT id, post_id, relation, userID, file_format FROM media WHERE userID = '".$user['id']."' AND relation = 'profile_picture' UNION ALL SELECT -1 id, '55529055162cf' post_id, 'profile_picture' relation, '0' userID, 'jpg' file_format ORDER BY id DESC";
$qppimg = $conn->query($query_ppimage);
while($ppimg = mysqli_fetch_assoc($qppimg)) {
$rows[] = $ppimg;
$rows[] = $user;
}
}
Here is how the array is returned:
[
{
"id": "117",
"post_id": "1",
"relation": "profile_picture",
"userID": "3",
"file_format": "jpg"
},
{
"id": "3",
"email": "casper#socialnetwk.com",
"type": "user"
},
]
How it should look, or something similar. I don't think I named the sub array correctly, but it needs a name ppimage
[
{
"id": "3",
"email": "casper#socialnetwk.com",
"type": "user"
ppimage: {
"id": "117",
"post_id": "1",
"relation": "profile_picture",
"userID": "3",
"file_format": "jpg"
}
},
]
You are adding to $rows twice and appending two separate elements. Try building your array element first and then adding it into the $rows array. Something like this:
$newrow = $user;
$newrow['ppimage'] = $ppimg;
$rows[] = $newrow;
Using JOIN, you could limit this to one single query. Having a query inside a loop is never a good idea, and you should avoid it if you can. Furthermore, you should use prepared statements in order to protect against SQL injection.
The code below uses a JOIN, so that you just get one query - and structures the array as shown in the example. This is hard-coded, as its easier to control what goes where, since we now use a JOIN, the data is all fetched at once (and not in separate variables).
$row = array();
$stmt = $conn->prepare("SELECT m.id, m.post_id, m.relation, m.file_format, u.id, u.email, 'user' as type
FROM media m
JOIN users u ON u.id=m.userID
WHERE m.relation = 'profile_picture'
AND (username LIKE ?
OR firstname LIKE ?
OR lastname LIKE ?)
ORDER BY m.id DESC");
$stmt->bind_param("sss", $query, $query, $query);
$stmt->execute();
$stmt->bind_result($mediaID, $postID, $relation, $file_format, $userID, $user_email, $type);
while ($stmt->fetch()) { // If you just expect one row, use LIMIT in the query, and remove the loop here
$row[] = array('id' => $userID,
'email' => $user_email,
'type' => $type,
'ppimage' => array('id' => $mediaID,
'post_id' => $postID,
'relation' => $relation,
'userID' => $userID,
'file_format' => $file_format)
);
}
$stmt->close();
How can I prevent SQL injection in PHP?
MySQL JOIN

how to calculate the sum of grades for each student

I have one table for the grades of exams, and another for students (the students table will always have 10 students only).
I want to output an array in Json format for students details with the sum of grades of each by semester in array of array.
expected output
[
{
"id": "1", -> this is the semester ID
"student1": {"id": "1","name": "student name", "bio": "50", "chem": "50", "math": "60", "total grades": "160"},
"student2": {"id": "2","name": "secondstudent name", "bio": "60", "chem": "60", "math": "50", "total grades": "170"},
}
]
here is my tables structure
tbStudents
id , name
1 , student name
2 , secondstudent name
3 , thirdstudent name
tbGrades
id , student , semster , bio , chem , math , total
1 , 1 , 1 , 50 , 50 , 60 , 160
2 , 2 , 1 , 30 , 40 , 20 , 90
3 , 2 , 1 , 30 , 20 , 30 , 80
challenge
How to calculate the SUM of each bio, chem, math, total for each student by semester, cause the student might have multiple grades in the same semester
what i've tried
$sql = "SELECT grade.id g_id, grade.semester g_semester, grade.bio g_bio, grade.chem g_chem, grade.math g_math, grade.total g_total, student.id s_id, student.name s_name FROM tbGrades AS grade INNER JOIN tbStudents AS student ON student.id = grade.student";
try {
$db = new db();
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->execute();
$grade = $stmt->fetchAll(PDO::FETCH_OBJ);
$db = null;
if(empty($grade)) {
$response->getBody()->write
('
{
"error":
{
"status":"400",
"message":"Invalid Request"
}
}');
} else {
foreach($grade as $value) {
$array_resp[]=[
'id' => $value->g_id,
'student1' => ['id'=>$value->s_id, 'name'=>$value->s_name, 'bio'=>$value->g_bio, 'chem'=>$value->g_chem, 'math'=>$value->g_math, 'total grades'=>$value->g_total],
];
}
$response->getBody()->write(json_encode($array_resp));
}
} catch(PDOException $e) {
$response->getBody()->write
('
{
"error":
{
"message":'. $e->getMessage() .'
}
}');
}
You can do it easily using MySQL GROUP BY clause.
SELECT
grade.id g_id,
grade.semester g_semester,
SUM(grade.bio) g_bio,
SUM(grade.chem) g_chem,
SUM(grade.math) g_math,
SUM(grade.total) g_total,
student.id s_id,
student.name s_name
FROM
tbGrades AS grade
INNER JOIN
tbStudents AS student
ON
student.id = grade.student
GROUP BY
student.id,
grade.semester

Categories