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.
Related
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>";
}
}
I am requesting your advice about the following:
I have two tables:
Customers and Orders.
I am printing the data of customers inside a table using a while loop:
$sql = "SELECT * FROM wccrm_customers where status = '1' order by date desc";
$result = mysql_query($sql, $db);
while ($daten = mysql_fetch_array($result)) { ?>
echo $daten[id];
echo $daten[name] . ' ' . $daten[vorname];
echo $daten[email];
echo $daten[telefon];
} ?>
Now I try to add a new field in this list: Purchased YES/NO. As we have more customers then buyers, we want to show whether someone has bought or not:
The Connection between this two tables is the first/lastname in both tables!
So if customer.name = orders.name and customer.firstname = orders.firstname I want to echo "YES" if not then "NO"
I tried with a JOIN, but here I just get the results who are in both table:
SELECT *
FROM wccrm_customers AS k
INNER JOIN wccrm_orders AS o
ON o.namee = k.name AND o.firstname = k.firstname
but I need to have all of the customers and the ones who are in both lists marked...
Is this possible? If yes: How can I achieve this?
Thank's for your advice!
Kind regards,
Stefan
This has nothing to do with PHP, or with while loops; you just need to form your join properly:
SELECT DISTINCT
`k`.*,
`o`.`namee` IS NOT NULL AS `Purchased`
FROM `wccrm_customers` AS `k`
LEFT JOIN `wccrm_orders` AS `o`
ON
`o`.`namee` = `k`.`name`
AND `o`.`firstname` = `k`.`firstname`
Read more about the different join types: http://www.sql-join.com/sql-join-types/
(images courtesy of that site, which also contains an example and discussion of almost exactly what you're trying to do!)
By the way, you must have missed the massive red warning banner in the manual about using the deprecated (now removed) mysql_* functions. You should stop doing that! Use MySQLi or PDO instead.
a shorter one
SELECT DISTINCT k.*, IF(o.namee IS NULL, 'no', 'yes') purchased
FROM
wccrm_customers AS k
LEFT JOIN wccrm_orders AS o USING (namee,firstname)
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?
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
I have records in my database but I can't display them. Can someone check my codes, please. I'm just an amateur web developer. Thanks for any help.
<?php
$groups=mysql_query("SELECT * FROM groups ORDER BY id ASC");
$g_res=mysql_affected_rows();
if($g_res>0)
{
while($row=mysql_fetch_array($groups))
{
$g_id=$row['id'];
$g_name=$row['g_name'];
$members=mysql_query("SELECT * FROM members WHERE group='$g_id'");
$m_res=mysql_affected_rows();
if($m_res>0)
{
while($row2=mysql_fetch_array($members))
{
$m_id=$row2['id'];
$m_name=$row2['m_name'];
$m_email=$row2['m_email'];
echo "<tr><td>$m_name<br/>($g_name)</td><td>$m_email</td></tr>";
}
}
else
{
echo "<tr><td colspan=2>Nothing to display</td></tr>";
}
}
}
else
{
echo "<tr><td colspan=2>Error</td></tr>";
}
?>
With this code I get the else result which is Error. If I remove WHERE group='$g_id' from the query, all of my records are displayed randomly, but I'd like to show my records (members) by group.
You need to escape reserved words in MySQL like group with backticks
SELECT * FROM members WHERE `group` = '$g_id'
^-----^-------------here
You can also spare the inner loop when you join your data like this
select g.id as gid, g.g_name, m.id as mid, m.m_name, m.m_email
from groups g
inner join members m on g.id = m.group
order by g.id asc
This is easier and will increase performance since you don't need to execute a lot of queries but just one.
Also please don't use mysql_* functions in new code.
They are no longer maintained and are officially deprecated.
Learn about Prepared Statements instead, and use PDO or MySQLi. See this article for a quick overview how to do it and why it is so important.
Try like
$members=mysql_query("SELECT * FROM members WHERE `group` = '".$g_id."');
or simply
$members=mysql_query("SELECT * FROM members WHERE `group` = '$g_id'");
You have to concatenate your variables.
Try this:
$members=mysql_query("SELECT * FROM members WHERE `group`='".$g_id."'");
And
echo "<tr><td>".$m_name."<br/>(".$g_name.")</td><td>".$m_email."</td></tr>";