I successfully did a LEFT JOIN using PHP, however, I am having a little difficulty adding a WHERE clause to enable me select unique record from all existing details in all the tables where a match is found.
This is my code :
<?php
$sql = "SELECT staff.*, staff_bio.bio_id, staff_cert.*, staff_edu.*, staff_pos.*, staff_res.*\n"
. " FROM staff staff\n"
. "LEFT JOIN staff_bio \n"
. " ON staff.nuc_id = staff_bio.bio_id\n"
. "LEFT JOIN staff_cert\n"
. " ON staff.nuc_id = staff_cert.pro_id\n"
. "LEFT JOIN staff_edu\n"
. " ON staff.nuc_id = staff_edu.edu_id\n"
. "LEFT JOIN staff_pos\n"
. " ON staff.nuc_id = staff_pos.rank_id\n"
. "LEFT JOIN staff_res\n"
. " ON staff.nuc_id = staff_res.res_id\n"
. "WHERE staff.nuc_id = $userRow['staff_no'] ";//this is where i'm having issues
?>
My final output should be something like :
<?php echo $userRow['sch_name']; ?>
<?php echo $userRow['fac_name']; ?>
<?php echo $userRow['dep_name']; ?>
All coming from different tables. Any help will be greatly appreciated.
You can do like this:
. " WHERE staff.nuc_id = ".$userRow['staff_no'] ;//this is where i'm having issues
Why do you need to concatenate query, it can be written as if you want formatting :
<?php
$sql = "SELECT staff.*, staff_bio.bio_id, staff_cert.*, staff_edu.*, staff_pos.*, staff_res.*
FROM staff staff
LEFT JOIN staff_bio
ON staff.nuc_id = staff_bio.bio_id
LEFT JOIN staff_cert
ON staff.nuc_id = staff_cert.pro_id
LEFT JOIN staff_edu
ON staff.nuc_id = staff_edu.edu_id
LEFT JOIN staff_pos
ON staff.nuc_id = staff_pos.rank_id
LEFT JOIN staff_res
ON staff.nuc_id = staff_res.res_id
WHERE staff.nuc_id = ".$userRow['staff_no'];//this is where i'm having issues
?>
Related
I'm trying to do a SQL join to return records from one table for users who don't have a corresponding entry in a second table against the record in the first table. The query I'm trying is below, which I think should return what I want, but it's giving a syntax error:
$query = "SELECT * FROM `suppliers` LEFT OUTER JOIN `matches` ON suppliers.supplierid = matches.supplier_id WHERE '" . $_SESSION['userEmail'] . "' NOT IN matches.user";
Any ideas or suggestions? What I'm trying to achieve from the above is to only show results for which the logged in user hasn't marked the supplier record as viewed.
TIA
$query = "SELECT * FROM `suppliers` LEFT OUTER JOIN `matches` ON suppliers.supplierid = matches.supplier_id WHERE matches.user NOT IN '" . $_SESSION['userEmail'] . "'";
not in clause not added properly.
correct your where clause :
$query = "SELECT * FROM `suppliers` LEFT OUTER JOIN `matches` ON suppliers.supplierid = matches.supplier_id WHERE matches.user NOT IN ('" . $_SESSION['userEmail'] . "') ";
OR if it is single value then you can use != instead of not in
$query = "SELECT * FROM `suppliers` LEFT OUTER JOIN `matches` ON suppliers.supplierid = matches.supplier_id WHERE matches.user != '" . $_SESSION['userEmail'] . "' ";
You should swap your WHERE Conditions and trim with brackets ().
$query = "
SELECT * FROM `suppliers` LEFT OUTER JOIN `matches`
ON suppliers.supplierid = matches.supplier_id
WHERE matches.user NOT IN ('" . $_SESSION['userEmail'] . "')
";
Your logic is just not correct. You can use LEFT JOIN, but the query should look like:
SELECT s.*
FROM suppliers s LEFT OUTER JOIN
matches m
ON m.supplierid = s.supplier_id AND
m.user IN ('" . $_SESSION['userEmail'] . "')
WHERE m.supplierid IS NULL;
Note: This row may be causing a syntax error or unexpected results:
m.user IN ('" . $_SESSION['userEmail'] . "')
You will need to look at the syntax after variable substitution to figure that one out. This answer addresses the logic of the query, so it will do what you actually want when the syntax is fixed.
I want to build a search engine for a webpage. I use the code below. The problem is, that I have to build the queries from different strings and if the system searches for matching in strings, quote marks are needed.
$sql = "SELECT TIT,VNEV,KNEV,NEME,MEGY,LCVAR,APOLG FROM TORZS LEFT OUTER JOIN VEGZETTSEG ON TORZS.ID = VEGZETTSEG.ID LEFT OUTER JOIN SZTAPASZTALAT ON TORZS.ID = SZTAPASZTALAT.ID LEFT OUTER JOIN SZAKTANFOLYAM ON TORZS.ID = SZAKTANFOLYAM.ID LEFT OUTER JOIN INFORM ON TORZS.ID = INFORM.ID WHERE ";
for ($i = 0;$i < count($searchcategs);$i++) {
$sql = $sql . $searchcategs[$i];
$sql = $sql . " = ";
$sql = $sql . $searchvals[$i];
$sql = $sql . " ";
}
An alternative version:
$sql = "SELECT TIT,VNEV,KNEV,NEME,MEGY,LCVAR,APOLG FROM TORZS LEFT OUTER JOIN VEGZETTSEG ON TORZS.ID = VEGZETTSEG.ID LEFT OUTER JOIN SZTAPASZTALAT ON TORZS.ID = SZTAPASZTALAT.ID LEFT OUTER JOIN SZAKTANFOLYAM ON TORZS.ID = SZAKTANFOLYAM.ID LEFT OUTER JOIN INFORM ON TORZS.ID = INFORM.ID WHERE ";
for ($i = 0;$i < count($searchcategs);$i++) {
$sql = $sql . $searchcategs[$i];
$sql = $sql . " = '";
$sql = $sql . $searchvals[$i];
$sql = $sql . "' ";
}
None of them seems to work, I got
SELECT TIT,VNEV,KNEV,NEME,MEGY,LCVAR,APOLG FROM TORZS LEFT OUTER JOIN VEGZETTSEG ON TORZS.ID = VEGZETTSEG.ID LEFT OUTER JOIN SZTAPASZTALAT ON TORZS.ID = SZTAPASZTALAT.ID LEFT OUTER JOIN SZAKTANFOLYAM ON TORZS.ID = SZAKTANFOLYAM.ID LEFT OUTER JOIN INFORM ON TORZS.ID = INFORM.ID WHERE
for the query even though the searchcateg and searchval arrays are existing and not empty.
The select query below returns 1 row when it should be 3. I am pretty sure it is because of the AVG(k.sumtotal) field.
If I rewrite the query and take out that AVG(k.sumtotal) column and take out the FROM inv_ratings AS k, I get my 3 rows.
I can't figure out why this table (inv_ratings) or this AVG(k.sumtotal) column restrict the number of rows to 1. I looked online for hours trying to find information about returning results using the AVG clause and didn't find much. Do I have to use a group by clause, I tried that and only get errors.
$p = "SELECT i.invention_id, i.inv_title, i.date_submitted, i.category_id,"
. " i.approved, c.category_id, c.category, u.image_name, AVG(k.sumtotal)"
. " FROM inv_ratings AS k INNER JOIN inventions AS i USING (invention_id)"
. " INNER JOIN categories AS c USING (category_id)"
. " INNER JOIN images AS u USING (invention_id)"
. " WHERE c.category_id = $cat AND i.approved = 'approved'"
. " HAVING u.image_name < 2"
. " ORDER BY date_submitted"
. " DESC LIMIT $start, $display";
$q = mysqli_query($dbc, $p) or trigger_error("Query: $p\n<br />mysqli Error: " . mysqli_error($dbc));
You are running into one of MySQL's gotchas:
http://dev.mysql.com/doc/refman/5.5/en/group-by-handling.html
I hate that MySQL ever allows this syntax because it only causes confusion. But what you probably want is (to use MySQL's hackish behavior, please note that if there are multiple values for any of the fields besides invention_id or sumtotal, you get a random value from that column):
$p = "SELECT i.invention_id, i.inv_title, i.date_submitted, i.category_id,"
. " i.approved, c.category_id, c.category, u.image_name, AVG(k.sumtotal)"
. " FROM inv_ratings AS k INNER JOIN inventions AS i USING (invention_id)"
. " INNER JOIN categories AS c USING (category_id)"
. " INNER JOIN images AS u USING (invention_id)"
. " WHERE c.category_id = $cat AND i.approved = 'approved'"
. " GROUP BY i.invention_id "
. " HAVING u.image_name < 2"
. " ORDER BY date_submitted"
. " DESC LIMIT $start, $display";
Or, to not use MySQL's hackish behavior:
$p = "SELECT i.invention_id, i.inv_title, i.date_submitted, i.category_id,"
. " i.approved, c.category_id, c.category, u.image_name, AVG(k.sumtotal)"
. " FROM inv_ratings AS k INNER JOIN inventions AS i USING (invention_id)"
. " INNER JOIN categories AS c USING (category_id)"
. " INNER JOIN images AS u USING (invention_id)"
. " WHERE c.category_id = $cat AND i.approved = 'approved'"
. " GROUP BY i.invention_id, i.inv_title, i.date_submitted, i.category_id,"
. " i.approved, c.category_id, c.category, u.image_name "
. " HAVING u.image_name < 2"
. " ORDER BY date_submitted"
. " DESC LIMIT $start, $display";
I have a Query that populates $row["app_id"] and as I go through my div id="reveal" that app_id changes. What I'm trying to do is plug that app_id in the $revealstmt query. I keep receiving error.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid
parameter number: number of bound variables does not match number of tokens
My code is as follows
<?php
$revealid = $row["app_id"];
while (isset($revealid)){
$query3 = "";
$revealstmt = $conn->prepare("SELECT logs.time_entry AS logs_entry, logs.description AS logs_description, substates.name AS reveal_substates_name FROM logs LEFT OUTER JOIN applications ON logs.fk_app_id = applications.pk_app_id LEFT OUTER JOIN substates ON logs.fk_substate_id = substates.pk_substate_id WHERE logs.fk_app_id = <?php echo $revealid ?> and time_entry >= curdate() - INTERVAL DAYOFWEEK(curdate()) + 14 DAY ORDER BY time_entry DESC;");
$revealstmt->execute(array('query3' => $query3));
?>
<div id="<?php echo $row["app_name"];?>" class='reveal-modal'>
<div id="reveal">
<h1><?php echo $row["app_name"]; echo $revealid; ?>
<br />
</h1>
<div class="accordion">
<?php while ($revealrow = $revealstmt->fetch()){?>
<h3><a href=""><?php echo $revealrow["logs_entry"]?> -|- <?
php echo $revealrow["reveal_substates_name"]; ?></a></h3>
<div><?php echo $revealrow["logs_description"]; ?></div>
<?php } ?> <!-- Close Tag for $revealrow -->
<?php } ?> <!-- Close tag for the while(isset) -->
I've tried using foreach but cannot as $row["app_id"] isn't an array it only returns 1 number at a time.
Hopefully I've given all the information needed, if not will of course add whatever I need to. Thanks again to the community for all of your help!
I believe your query prepare statement has the wrong syntax. Try this:
$revealstmt = $conn->prepare("SELECT logs.time_entry AS logs_entry, logs.description AS logs_description, substates.name AS reveal_substates_name FROM logs LEFT OUTER JOIN applications ON logs.fk_app_id = applications.pk_app_id LEFT OUTER JOIN substates ON logs.fk_substate_id = substates.pk_substate_id WHERE logs.fk_app_id = ".$revealid." and time_entry >= curdate() - INTERVAL DAYOFWEEK(curdate()) + 14 DAY ORDER BY time_entry DESC;");
If you echo the value it should go to stdout and not to the string/query you are preparing.
You should use concatenation instead in your query. Besides, you don't want queries that long. In the same way you wouldn't write all your PHP in one line, the same goes for your MySQL: it's another language.
$revealstmt = $conn->prepare(
"SELECT logs.time_entry AS logs_entry, " .
"logs.description AS logs_description, " .
"substates.name AS reveal_substates_name " .
"FROM logs LEFT OUTER JOIN applications " .
"ON logs.fk_app_id = applications.pk_app_id " .
"LEFT OUTER JOIN substates ON logs.fk_substate_id = substates.pk_substate_id " .
"WHERE logs.fk_app_id = " . $revealid . " AND " .
"time_entry >= curdate() - INTERVAL DAYOFWEEK(curdate()) + 14 DAY " .
"ORDER BY time_entry DESC;");
$revealstmt->execute();
Another problem is that you were trying to assign query3 to something. There was no ? placeholder in your query, thus, no need to add anything in your execute(). However, the other working solution can be not secure depending on where your $revealid comes from. You can make it secure by doing this:
$revealstmt = $conn->prepare(
"SELECT logs.time_entry AS logs_entry, " .
"logs.description AS logs_description, " .
"substates.name AS reveal_substates_name " .
"FROM logs LEFT OUTER JOIN applications " .
"ON logs.fk_app_id = applications.pk_app_id " .
"LEFT OUTER JOIN substates ON logs.fk_substate_id = substates.pk_substate_id " .
"WHERE logs.fk_app_id = ? AND " .
"time_entry >= curdate() - INTERVAL DAYOFWEEK(curdate()) + 14 DAY " .
"ORDER BY time_entry DESC;");
$revealstmt->execute(array($revealid));
$revealstmt->execute(array('query3' => $query3)); this is your problem, your query have no binding values but still you are sending an array of bindings on your execute statment.
Try this one:
$revealstmt = $conn->prepare("SELECT logs.time_entry AS logs_entry, logs.description AS logs_description, substates.name AS reveal_substates_name FROM logs LEFT OUTER JOIN applications ON logs.fk_app_id = applications.pk_app_id LEFT OUTER JOIN substates ON logs.fk_substate_id = substates.pk_substate_id WHERE logs.fk_app_id = :query3 and time_entry >= curdate() - INTERVAL DAYOFWEEK(curdate()) + 14 DAY ORDER BY time_entry DESC;");
and then you execute yout query by passing the binding values like so:
$revealstmt->execute(array('query3' => $revealid));
OR :
$revealstmt->bindValue(':query3', $revealid);
Below is my SQL Query which i am able to run successfully in PhpMyAdmin .
[ data from multiple tables similar to IMDB database ]
SELECT
`data`.`code`,
`data`.`movie`,
`movies`.`id`,
`movies`.`name`,
`data`.`person`,
`persons`.`name`,
`persons`.`code`,
`data`.`mode`,
`modes`.`name`
FROM
`data`
INNER JOIN `movies` ON (`data`.`movie` = `movies`.`id`)
INNER JOIN `persons` ON (`data`.`code` = `persons`.`code`)
INNER JOIN `modes` ON (`data`.`mode` = `modes`.`code`)
where `data`.`movie`=1
Below is PHP CODE generated by PhpMyAdmin (create PHP Code button) from above command but not fetching any results when used in PHP page (webpage) ,
$sql = "SELECT \n"
. " `data`.`code`,\n"
. " `data`.`movie`,\n"
. " `movies`.`id`,\n"
. " `movies`.`name`,\n"
. " `data`.`person`,\n"
. " `persons`.`name`,\n"
. " `persons`.`code`,\n"
. " `data`.`mode`,\n"
. " `modes`.`name`\n"
. "FROM\n"
. " `data`\n"
. " INNER JOIN `movies` ON (`data`.`movie` = `movies`.`id`)\n"
. " INNER JOIN `persons` ON (`data`.`code` = `persons`.`code`)\n"
. " INNER JOIN `modes` ON (`data`.`mode` = `modes`.`code`)\n"
. "where `data`.`movie`=1 LIMIT 0, 30 ";
Try
$sql = "SELECT
`data`.`code`,
`data`.`movie`,
`movies`.`id`,
`movies`.`name`,
`data`.`person`,
`persons`.`name`,
`persons`.`code`,
`data`.`mode`,
`modes`.`name`
FROM
`data`
INNER JOIN `movies` ON (`data`.`movie` = `movies`.`id`)
INNER JOIN `persons` ON (`data`.`code` = `persons`.`code`)
INNER JOIN `modes` ON (`data`.`mode` = `modes`.`code`)
where `data`.`movie`=1";
The \n and . from your question are not required.