Echo contents of JOIN SQL tables with MySQLi - php

I'm working on a system, and this module is supposed to echo the contents of the database.
It worked perfectly until I added some JOIN statements to it.
I've checked and tested the SQL code, and it works perfectly. What's not working is that part where I echo the content of the JOINed table.
My code looks like this:
$query = "SELECT reg_students.*, courses.*
FROM reg_students
JOIN courses ON reg_students.course_id = courses.course_id
WHERE reg_students.user_id = '".$user_id."'";
$result = mysqli_query($conn, $query);
if (mysqli_fetch_array($result) > 0) {
while ($row = mysqli_fetch_array($result)) {
echo $row["course_name"];
echo $row["course_id"];
The course_name and course_id neither echo nor give any error messages.
UPDATE: I actually need to increase the query complexity by JOINing more tables and changing the selected columns. I need to JOIN these tables:
tutors which has columns: tutor_id, t_fname, t_othernames, email, phone number
faculty which has columns: faculty_id, faculty_name, faculty_code
courses which has columns: course_id, course_code, course_name, tutor_id, faculty_id
I want to JOIN these tables to the reg_students table in my original query so that I can filter by $user_id and I want to display: course_name, t_fname, t_othernames, email, faculty_name

I can't imagine that the user_info table is of any benefit to JOIN in, so I'm removing it as a reasonable guess. I am also assuming that your desired columns are all coming from the courses table, so I am nominating the table name with the column names in the SELECT.
For reader clarity, I like to use INNER JOIN instead of JOIN. (they are the same beast)
Casting $user_id as an integer is just a best practices that I am throwing in, just in case that variable is being fed by user-supplied/untrusted input.
You count the number of rows in the result set with mysqli_num_rows().
If you only want to access the result set data using the associative keys, generate a result set with mysqli_fetch_assoc().
When writing a query with JOINs it is often helpful to declare aliases for each table. This largely reduces code bloat and reader-strain.
Untested Code:
$query = "SELECT c.course_name, t.t_fname, t.t_othernames, t.email, f.faculty_name
FROM reg_students r
INNER JOIN courses c ON r.course_id = c.course_id
INNER JOIN faculty f ON c.faculty_id = f.faculty_id
INNER JOIN tutors t ON c.tutor_id = t.tutor_id
WHERE r.user_id = " . (int)$user_id;
if (!$result = mysqli_query($conn, $query)) {
echo "Syntax Error";
} elseif (!mysqli_num_rows($result)) {
echo "No Qualifying Rows";
} else {
while ($row = mysqli_fetch_assoc($result)) {
echo "{$row["course_name"]}<br>";
echo "{$row["t_fname"]}<br>";
echo "{$row["t_othernames"]}<br>";
echo "{$row["email"]}<br>";
echo "{$row["faculty_name"]}<br><br>";
}
}

Related

Showing two different values depending on SESSION value in INNER JOIN

I have two different tables, one named users, and another named transactions. Transactions contains wallet1, wallet2, amount. Users contains user details such as firstname, lastname, and wallet. I am trying to display the corresponding first name and last name, depending on whether or not the SESSION_wallet is equal to wallet1 or wallet2 within transactions. I tried searching for a while, and came up with a solution for showing the correct display name for the first and last name making the transfer, however, I am trying to make it display the correct value for "Transfer to:"
Here is some of my code to get a better understanding of what I mean:
MySQLi Query:
$result2 = mysqli_query($link, "SELECT * FROM transactions INNER JOIN users ON transactions.wallet1 = users.wallet WHERE transactions.wallet1 = '" . $_SESSION["wallet"] . "' OR transactions.wallet2 = '" . $_SESSION["wallet"] . "' Order by transactions.id DESC LIMIT 5 ");
PHP Code:
<?php
if(mysqli_num_rows($result2) > 0)
{
while($row = mysqli_fetch_array($result2))
{
?>
The table that needs to display the transfer from, and transfer to:
<?php
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["firstname"]." ".$row["lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["firstname"]." ".$row["lastname"]."</td>";
}
?>
Right now my tables are only showing the first and last name of the user that made the Transfer, however, I need it to display the first and last name of the user that the transaction is made to as well. The else if code is working correct, but the first part is not showing the corresponding value.
You will need to JOIN your transactions table to your users table twice, once to get each users name. Then to avoid duplicate column names overwriting the results in the output array, you will need to use column aliases. Something like this should work:
$result2 = mysqli_query($link, "SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = '{$_SESSION["wallet"]}'
OR t.wallet2 = '{$_SESSION["wallet"]}'
ORDER BY t.id DESC
LIMIT 5 ");
Then you can access each user's names as $row['w1_firstname'] etc.:
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["w2_firstname"]." ".$row["w2_lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["w1_firstname"]." ".$row["w1_lastname"]."</td>";
}
Note that ideally you should use a prepared query for this, for example:
$stmt = $link->prepare("SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = ?
OR t.wallet2 = ?
ORDER BY t.id DESC
LIMIT 5");
$stmt->bind_param('ss', $_SESSION["wallet"], $_SESSION["wallet"]);
$stmt->execute();
$result2 = $stmt->get_result();

Left Join With Null value Table

I was using this query to connect my student table and attendance table,
My Problem is, sometimes, attendance table has no value.
It's not returning any value.
<?php
if($_SERVER['REQUEST_METHOD']=="POST"){
include('include/connection.php');
showData();
}
function showData(){
global $connect;
$teacher_id = $_POST['teacher_id'];
$subject_id = $_POST['subject_id'];
$date = $_POST['date'];
$query ="
SELECT s.student_name
, s.student_number
, s.student_section
, s.subject_id
, s.fingerprint_id
, s.teacher_id
, a.status
FROM tbl_student s
LEFT
JOIN tbl_attendance a
on s.subject_id=a.subject_id
WHERE s.subject_id = '$subject_id'
and a.date='$date'
and s.teacher_id = '$teacher_id';";
$result =mysqli_query($connect,$query);
$number_of_rows = mysqli_num_rows($result);
$temp_array=array();
if($number_of_rows>0){
while($row=mysqli_fetch_assoc($result)){
$temp_array[]=$row;
}
}
header('Content-Type: application/json');
echo json_encode(array("student"=>$temp_array));
mysqli_close($connect);
}
?>
What I want to achive is even if attendance table has no value,
I can still see the student fields.
Is it even possible with SQL query? Thanks
You have to move the fields of table attendance from where to the on condition:
$query ="SELECT student.student_name,student.student_number,student.student_section,student.subject_id,student.fingerprint_id,student.teacher_id,attendance.status
FROM tbl_student student
LEFT JOIN tbl_attendance attendance on student.subject_id=attendance.subject_id and attendance.date='$date'
WHERE student.subject_id='$subject_id' and student.teacher_id='$teacher_id';";
Because first the join Statement will be executed and then the where, if you access the table tbl_attendance in where ans all the columns are null, they will filtered out.
Hint: read about prepared Statements to provide SQL-injection
SELECT student.student_name,student.student_number,student.student_section,student.subject_id,student.fingerprint_id,student.teacher_id,attendance.status
FROM tbl_student student
LEFT JOIN tbl_attendance attendance on student.subject_id=attendance.subject_id and attendance.date='$date'
WHERE student.subject_id='$subject_id' and student.teacher_id='$teacher_id';
Try above code.Hope this will helps.
As you had made condition on student table using attendance.date='$date' on WHERE clause it exclude that record which are not satisfy this condition.
So instead of where i had put that condition through ON clause on LEFT JOIN.
This will achieve your goal.

For each SQL result, another SQL query? in PHP

I need help at getting data from MySQL Database. Right now I have a query that gives me:
Tournament ID
Tournament Name
Tournament Entry fee
Tournament Start and End date
For tournaments I am registered in. Now I want, for each tournament I am registered in, to count how many users are in that tournament, my points in that tournament, etc.
That info is in table called 'ladder'
ladder.id
ladder.points
ladder.userFK
ladder.tournamentFK
Database: http://prntscr.com/99fju1
PHP CODE for displaying tournaments I am registered in:
<?php
include('config.php');
$sql = "SELECT distinct tournaments.idtournament, tournaments.name, tournaments.entryfee, tournaments.start, tournaments.end
from tournaments join ladder
on tournaments.idtournament= ladder.tournamentFK and ladder.userFK=".$_SESSION['userid']."
group by tournaments.idtournament";
$result = $conn->query($sql);
if($result->num_rows > 0){
while($row = $result->fetch_assoc()) {
$tournament="<li class='registered' data-id=".$row['idtournament']." data-entryfee=".$row['entryfee']." data-prize=".$tournamentPrize."><span class='name'>".$row['name']."</span><span class='entry-fee'>Entry fee: ".$row['entryfee']."€</span><span class='prize-pool'>Prize pool: €</span><span class='date-end'>".$row['start']."-".$row['end']."</span><span class='btns'><button>Standings</button></span></li>";
echo $tournament;
}
}
$conn->close();
?>
Usually you can combine JOIN, COUNT() and GROUP BY in your query.
Some examples:
MySQL joins and COUNT(*) from another table
This would be the query I think.Change column and table name if its not correct. Not tested but I am sure this will give you some idea to make required query
select count(ladder.tournamentId)as userCount,tournaments.name
from
ladder left join tournaments
on ladder.tournamentId = tournaments.id
where ladder.tournamentId in
(
select tournaments.id from
tournaments left join ladder
on ladder.tournamentId = tournaments.id
where ladder.userId='yourId'
) and ladder.userId <> 'yourId'
group by ladder.tournamentId

MYSQL query so it also returns values if has no value in the other table

Hi guys in the code below you can see what my JSON returns.
{"lifehacks":[{
"id":"2",
"URLtoImage":"http:\/\/images.visitcanberra.com.au\/images\/canberra_hero_image.jpg",
"title":"dit is nog een test",
"author":"1232123",
"score":"2",
"steps":"fdaddaadadafdaaddadaaddaadaaaaaaaaaaa","category":"Category_2"}]}
What the JSON returns is fine. The only problem is it is only displaying lifehacks if it has one like or more. So what should I change about my Query so it would display lifehacks without likes aswell.
//Select the Database
mysql_select_db("admin_nakeitez",$db);
//Replace * in the query with the column names.
$result = mysql_query("select idLifehack, urlToImage, title, Lifehack.Users_fbId, idLifehack, steps, Categorie, count(Lifehack_idLifehack) as likes from Lifehack, Likes where idLifehack = Lifehack_idLifehack AND idLifehack > " . $_GET["id"]. " group by idLifehack;", $db);
//Create an array
$json_response = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$row_array['id'] = $row['idLifehack'];
$row_array['URLtoImage'] = $row['urlToImage'];
$row_array['title'] = $row['title'];
$row_array['author'] = $row['Users_fbId'];
$row_array['score'] = $row['likes'];
$row_array['steps'] = $row['steps'];
$row_array['category'] = $row['Categorie'];
//push the values in the array
array_push($json_response,$row_array);
}
echo "{\"lifehacks\":";
echo json_encode($json_response);
echo "}";
//Close the database connection
fclose($db);
I hope my problem is clear like this. Thank you in advance I can't figure it out myself.
You need a LEFT JOIN here. Your query has an INNER JOIN.
select
idLifehack,
urlToImage,
title,
Lifehack.Users_fbId,
idLifehack,
steps,
Categorie,
count(Lifehack_idLifehack) as likes
from Lifehack
left join Likes on idLifehack = Lifehack_idLifehack
where idLifehack > whatever
group by idLifehack;
There's an excellent explanation of the different join types here.
A couple additional points...
Use prepared statements in your PHP. Your code is wide-open to SQL Injection, which has ruined careers and led to millions of innocent people having their personal information stolen. There are plenty of web sites showing how to do this so I won't go into it here, though I'll say my favorite is bobby-tables.
Avoid the implicit join anti-pattern in your queries. This is an implicit join:
FROM a, b
WHERE a.id = b.id
Use explicit joins instead; they separate your join logic from your filtering (WHERE) logic:
FROM a
INNER JOIN b ON a.id = b.id

How to optimize nested query with PHP and MySqli?

I have this code, that fetches data from two tables in MySQLi.
It first has to get the title, description, status and project_id from table 1, and then get the name from table 2 using the id from table 1.
Is there a better/faster way to do this? I have about 600 rows in the tables, and it takes about 5 sec to run this query. I will also add that this example is a bit simplified, so please don't comment on the db-structure.
<?php
$results = $connect()->db_connection->query(
'SELECT title, description, status, project_id
FROM table
WHERE created_by ='.$user_id
);
if ($results) {
while ($result = $results->fetch_object()) {
$res = $connect()->db_connection->query(
"SELECT name FROM projects WHERE id = ".$result->project_id
);
if ($res) {
while ($r = $res->fetch_object()) {
echo $r->name;
}
}
echo $result->title;
echo $result->status;
}
}
?>
Use Query:
SELECT title,description,status,project_id
FROM table tb
inner join projects pr on pr.id = tb.project_id
WHERE created_by = $user_id
Try to use JOIN in your query.
You can find examples and description of this command here: http://www.w3schools.com/sql/sql_join.asp
Check out also this infographics:
http://www.codeproject.com/KB/database/Visual_SQL_Joins/Visual_SQL_JOINS_orig.jpg
You can use JOIN on project_id:
$results = $connect()->db_connection->query('SELECT t.title title,t.description,t.status status,t.project_id, p.name name FROM `table` t JOIN projects p ON p.id= t.project_id WHERE t.created_by ='.$user_id);
if($results){
while($result = $results->fetch_object()){
echo $result->name;
echo $result->title;
echo $result->status;
}
}
tables have aliases here - t for table and p for projects.
Also to make it faster, add index to project_id in table table, if you haven't done it yet:
$connect()->db_connection->query('ALTER TABLE `table` ADD INDEX `product_id`');

Categories