how to get data from multiple tables on sql php - php

I'm currently making a table result based on PHP & mySQL, I encountered a problem where I would be pulling multiple data in tables with multiple condition, I also got error (mysqli_fetch_array() expects parameter 1 to be mysqli_result). Here are some of the codes:
<?php
include('mysql.php');
mysqli_select_db($con,"iiumsystem");
$id = $_GET['id'];
$sql = "SELECT stu_id, org_name, suv_id, stu_mark
FROM (SELECT * FROM student
INNER JOIN organization
ON org_name.stu_id = stu_id
WHERE (student.stu_id = '?' OR organization.stu_id ='?')) AS matches
INNER JOIN supervisor
ON suv_id.stu_id = stu_id
WHERE (student.stu_id = '?' OR supervisor.stu_id ='?')) AS matches
INNER JOIN mark
ON stu_mark.stu_id = stu_id
WHERE (student.stu_id = '?' OR mark.stu_id ='?')) AS matches";
$result = mysqli_query($con,$sql);
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td class='result'>".$row['stu_id']."</td>";
echo "<td class='result'>".$row['suv_id']."</td>";
echo "<td class='result'>".$row['org_name']."</td>";
echo "<td class='result'>".$row['stu_mark']."</td>";
echo "</td>";
echo "</tr>";
}
echo "</tbody>";
echo "</table>";
mysqli_close($con);
?>

This clearly says you have some error in your sql query.
Try to print $sql query with parameters value in and run it into any mysql client i.e. phpmyadmin. It will show you correct query error.

SELECT stu_id, org_name, suv_id, stu_mark FROM
(SELECT * FROM student INNER JOIN organization ON org_name.stu_id = stu_id WHERE (student.stu_id = '?' OR organization.stu_id ='?'))
AS matches
INNER JOIN supervisor ON suv_id.stu_id = stu_id
WHERE (student.stu_id = '?' OR supervisor.stu_id ='?') AS matches
INNER JOIN mark
ON stu_mark.stu_id = stu_id
WHERE (student.stu_id = '?' OR mark.stu_id ='?') AS matches
Try this. You had two extra parantheses after the WHERE statements.

I'm not really sure what you're trying to do here, but all of those subqueries aren't going to help you.
SELECT student.stu_id, organization.org_name, supervisor.suv_id, mark.stu_mark
FROM student
INNER JOIN organization
ON organization.stu_id = student.stu_id
INNER JOIN supervisor
ON supervisor.stu_id = student.stu_id
INNER JOIN mark
ON mark.stu_id = student.stu_id
But I'm confused about your architecture here. From what I can make out of your query, it looks like there's a one-to-many relationship between student and each of supervisor, organization, and mark. I would expect the relationship to be:
student has one supervisor
student has one organization
student has many mark
In that case, student would have a org_id and suv_id field, while mark would have a stu_id field. You would then write the query as:
SELECT student.stu_id, organization.org_name, supervisor.suv_id
FROM student
LEFT JOIN organization
ON organization.org_id = student.org_id
LEFT JOIN supervisor
ON supervisor.sup_id = student.sup_id
And I'm not sure what you want to do with mark, since I assume you would have a lot of them. AVG(mark.stu_mark) maybe?

Related

Echo contents of JOIN SQL tables with MySQLi

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>";
}
}

select from two mysql tables where column value is similar and id is retrieved from previous page

i have a question. my english isn't well. so i hope i explain well...
i have two tables, tbl_home and tbl_office, the question is
how do i make a select statement from 2 tables which have identical value from column 'case_no' where it is referenced in both table..
$a=$_POST['home_id']
the code above is where i get the home_id from,
while the statement below is how i try to select both tables based on value in column 'case_no' of both table. but it is based on variable $a which i retrieved from form
<?php
$sql2 = "SELECT * FROM tbl_office WHERE case_no IN (SELECT * FROM tbl_home WHERE home_id = '$
$result2=$conn->query($sql2);
while($row = $result2->fetch_assoc()){
$a=$row['case_no'];
$bc=$row['colour'];
echo " $a <br/> ";
echo " $bc2 <br/>";
?>
is the select statement above correct??
soo, i just want anybody to take a look a this specific statement and how to make it right
$sql2 = "SELECT * FROM tbl_office WHERE case_no IN (SELECT * FROM tbl_home WHERE home_id = '$a'";
You need inner join to use:
" SELECT t_office.home_id,t_office.case_no,t_office.name FROM tbl_office
t_office INNER JOIN tbl_home t_home ON t_office.case_no = t_home.case_no;
where t_office.case_no ='$a'";
u can use "inner join" for example:
"SELECT t.home_id,t.case_no,t.name FROM tbl_office
t INNER JOIN tbl_home h ON h.case_no = h.case_no"
**select tbl_home.name,tbl_office.case_no,tbl_office.color from tbl_office
INNER JOIN tbl_home on tbl_office.case_no = tbl_home.case_no
where tbl_office.case_no ='$a';**
I hope this will be working fine until $a(case_no) value is existed in tbl_home or else it doesn't give any rows

PHP MySQL - How to fetch the SELECT GROUP_CONCAT,GROUP_BY two table?

I have two database tables like this and want to fetch to my website like this(see the screenshot)
But I can only fetch one table. I don't know how to use group by with JOIN
here is my code
$sql = "SELECT photographer,GROUP_CONCAT(free_image)
FROM free_images_table
GROUP BY photographer";
$result = mysqli_query($conn, $sql);
while($row = mysqli_fetch_assoc($result))
{
$free_image = explode(',', $row['GROUP_CONCAT(free_image)']);
echo "<tr>";
echo "<td>".$row['photographer_id']."</td>"; ?>
<td>
<?php
for($i=0; $i < count($free_image); $i++ )
{
echo $free_image[$i];
}
?></td>
echo "</tr>";
}
The special table may not have photographer (my website require only freeimage, the special image is optional.
This could be done using a LEFT JOIN (added column aliases for simplicity in php) -
SELECT free_images_table.photographer,
GROUP_CONCAT(DISTINCT free_images_table.free_image) as free_images,
GROUP_CONCAT(DISTINCT special_images_table.special_image) as special_images
FROM free_images_table
LEFT JOIN special_images_table
ON special_images_table.photographer = free_images_table.photographer
GROUP BY photographer
LEFT JOIN is used when you have a record in the 1st table, but not always a matching record in the 2nd table
Then in php, you would create your special image cells the same as your free image cells
$free_image = explode(',', $row['free_images']);
$special_image = explode(',', $row['special_images']);
...
SELECT table_1.free_image, table_2.special_image FROM table1 INNER JOIN table_2 ON table_1.photographer = table_2.photographer
In this case can use INNER JOIN.
Add table name before the field and INNER JOIN with same photographer.

PHP/MySQL INNER JOIN Triples the amount of rows?

I have a system where I getting images out of my database, but when it does that, there is 3x of the same images.
I have tried with different ways, DISTINCT and such, but I have no clue how I fix this.
Here is my query code:
<?php
$id = $_GET['id'];
$query = "SELECT DISTINCT * FROM billeder INNER JOIN album ON fk_album_ID = $id";
$result = mysqli_query($con, $query);
while($row = mysqli_fetch_assoc($result))
{
$thumb_src = 'billeder/thumb_'.$row['billeder_sti'];
$full_src = 'billeder/'.$row['billeder_sti'];
echo "
<div class='ikon'>
<a href='$full_src'>
<img src='$thumb_src' alt='' />
</a>
</div>
";
}
?>
Hope someone can help me on the way to fix this :)
Without being able to see your table structure I won't be able to give an exact answer but the likely reason is because your INNER JOIN is not setup correctly.
SELECT DISTINCT *
FROM billeder
INNER JOIN album
ON (billeder.fk_album_ID = album.pk_album_ID)
WHERE
billeder.fk_album_ID = $id
Something like the above would be the correct way to JOIN a table and using a WHERE clause to then limit the date received.
JOIN must be used with two tables columns. See example:
SELECT * FROM tableA a INNER JOIN tableB b ON a.id = b.a_id;
What you're trying to make is something like this:
"SELECT DISTINCT * FROM billeder INNER JOIN album ON
billeder.fk_album_ID = album.album_id WHERE billeder.id = $id"
You shouldn't pass an argument to the JOIN. The arguments must be used on the WHERE clause.

Comparing two MySQL tables to populate a dropdown

I'm trying to populate a dropdown menu by comparing two tables, one has a list of supervisor and employee numbers, the other has employee numbers and names. I need to take the numbers for each supervisor and employee and turn them into employee names for the drop down menu, so basically
TABLE payroll_employeelist
Supervisor Employee
1234 3456
1234 2239
1234 123
2910 338
2910 3901
TABLE payroll_users
number name
3456 John Smith
2239 Mary Jane
123 Joe Brown
etc
Supervisors are identified by a session variable callede $usernumber.
What I have so far and is returning one result (just one!) is the following:
if ($loademployees == 1){
echo "<option value=\"base\">---- Employee Name ----</option>";
$query = "SELECT payroll_employeelist.employee, payroll_users.number, payroll_users.name FROM payroll_employeelist WHERE supervisor='$usernumber' LEFT JOIN payroll_users ON payroll_employeelist.employee=payroll_users.number ";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
echo "<option value=\">" . $row{'name'} . "</option>";
}
echo "</select><br>";
}
Can anyone help with this? I get the feeling I've done something funny with the JOIN. It should look like a list of employee names in the dropdown.
UPDATE:
What I have now is:
if ($loademployees == 1){
echo "<option value=\"base\">---- Employee Name ----</option>";
$query = "SELECT payroll_employeelist.supervisor, payroll_employeelist.employee, payroll_users.number, payroll_users.name
FROM payroll_employeelist
INNER JOIN payroll_users
ON payroll_employeelist.employee = payroll_users.number
WHERE supervisor = '$usernumber' ";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
echo "<option value=\">" . $row['name'] . "</option>";
}
echo "</select><br>";
}
This is successfully returning one of the three records in the test data set, just one, the middle record. The $usernumber is generated internally by the way, no injection possible.
LAST UPDATE- SOLVED
The problem believe it or not was
echo "</select><br>";
it was echoing that before echoing the results of the while loop so it thought the options list was empty. I can't explain the randomly appearing single employee mind you, but it's working now.
You need to join payroll_users twice on table payroll_employeelist since there are two columns that are dependent on it.
SELECT sup.Name SupervisorName,
empName EmployeeName
FROM payroll_employeelist a
INNER JOIN payroll_users sup
ON a.Supervisor = sup.number
INNER JOIN payroll_users emp
ON a.Employee = emp.Number
WHERE sup.Supervisor = '$usernumber'
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
That's probably because you put the join condition inside the WHERE, but you probably meant to have it outside:
SELECT payroll_employeelist.employee, payroll_users.number, payroll_users.name
INNER JOIN payroll_users ON payroll_employeelist.employee=payroll_users.number
FROM payroll_employeelist
WHERE supervisor='$usernumber'
Also, if you use LEFT JOIN you will also get employees that are not attached to any user. A few things about escaping:
$query = "SELECT ... WHERE supervisor='$usernumber' ... ";
That's susceptible to SQL injection if $usernumber comes from a web request; consider using either mysql_real_escape_string() to escape it or switch to PDO / mysqli and use prepared statements instead.
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
echo "<option value=\">" . $row{'name'} . "</option>";
}
You should escape $row['name'] as well, and you shouldn't use curly braces either:
echo "<option value=\">" .
htmlspecialchars($row['name'], ENT_QUOTES, 'UTF-8') .
"</option>";
SELECT
tb1.supervisor,
tb1.employee,
tb2.name
FROM
payroll_employeelist AS tb1
INNER JOIN payroll_users AS tb2
ON tb1.employee = tb2.number
As you want exact matches, without non-matching values, you need INNER JOIN instead of LEFT JOIN
Use
SELECT payroll_employeelist.employee, payroll_users.number, payroll_users.name FROM payroll_employeelist LEFT JOIN payroll_users ON payroll_employeelist.employee = payroll_users.number WHERE supervisor = '$usernumber'
instead.
You should look at using PDO for your queries. Since you are dynamically assigning values into your query PDO will be a bit more secure, and if you're running this query multiple times it will be faster with PDO.
As for your query, you have your SQL Clauses ordered incorrectly. Perhaps these links will help:
PDO Tutorial from MySQL
SQL Join Tutorial
you have a mistake in your sintax
please check
$query = "SELECT payroll_employeelist.employee, payroll_users.number, payroll_users.name FROM payroll_employeelist WHERE supervisor='$usernumber' LEFT JOIN payroll_users ON payroll_employeelist.employee=payroll_users.number ";
should be
$query = "SELECT payroll_employeelist.`employee`, payroll_users.`number`, payroll_users.`name` FROM `payroll_employeelist` LEFT JOIN `payroll_users` ON payroll_employeelist.employee` = payroll_users.`number` WHERE `supervisor` = '$usernumber' ";
about this
WHERE `supervisor` = '$usernumber' ";
what table does supervisor is in? you need to fix with prefix payroll_employeelist or payroll_users
documentation here
I would like to also to remember you that mysql_ functions are deprecated so i would advise you to switch to mysqli or PDO for new projects.

Categories