I have very limited to zero knowledge about SQL or DBs, so apologies in advance.
I am attempting to make a table like structure within a webpage, a column for meal name, and a column for ingredients - it is also searchable via a button.
EDIT:
Thanks for all the replies, they have been most helpful.
The error no longer happens, however now I get no results from the database, but no error.
include("inc/dbConn.php"); /////$db_conx
if(isset($_POST["search"])){
$searchq = $_POST["search"];
$sql ="
SELECT main_meal.name, ingred.name
FROM main_meal
JOIN meal_ingred on meal_ingred.meal_id = main_meal.id
JOIN ingred ON ingred.id = meal_ingred.ingred_id
WHERE ingred.name LIKE '%$searchq%'";
$results = $db_conx->query($sql);
var_dump($results);
if($results->num_rows){
while ($row =$results->fetch_object()){
echo "{$row->name} ({$row->name})<br>";
}
}
}
For clarification here is my structure:
(Sorry for external link, I dont have enough reputation to post images.)
http://i30.photobucket.com/albums/c340/Tyrage/Untitled-2_zpsc48126b3.png
The $results dumps:
object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(2) ["lengths"]=> NULL ["num_rows"]=> int(0) ["type"]=> int(0) }
It is quite obvious I don't have a clue what I am doing, so any help is appreciated.
Thanks.
you're lacking a relation table here, which will store connection between meals and ingredients.
also you had error in your query because at first you've tried to use a/b naming correctly, to name a column, and then you user it to name a table.
IMHO you should do something like this (with relation table added):
if(isset($_POST["search"])){
$searchq = $_POST["search"];
$sql ="
SELECT main_meal.name AS a, ingred.name as b
FROM main_meal
JOIN rel_meal_ingred on rel_meal_ingred.meal_id = main_meal.id
JOIN ingred ON ingred.id = rel_meal_ingred.ingred_id
where ingred.name LIKE '%$searchq%'";
$results = $db_conx->query($sql);
if($results->num_rows){ //////line 15
while ($row =$results->fetch_object()){
echo "{$row->a} ({$row->b})<br>";
}
}
}
You could try this?
SELECT *
FROM main_meal
JOIN meal_ingred ON meal_ingred.meal_id = main_meal.id
JOIN ingred ON meal_ingred.meal_id = main_meal.id
WHERE ingred.ingredName LIKE '%bread%'
LIMIT 0 , 30
with the php as follow:
<?php
if(isset($_POST["search"])){
$searchq = $_POST["search"];
$sql ="
SELECT *
FROM main_meal
JOIN meal_ingred ON meal_ingred.meal_id = main_meal.id
JOIN ingred ON meal_ingred.meal_id = main_meal.id
WHERE ingred.ingredName LIKE '%$searchq%'
LIMIT 0 , 30
";
//$results = $db_conx->query($sql);
if (!$results = $db_conx->query($sql)) {
printf("Error: %s\n", $db_conx->error);
}
$count = $results->num_rows;
if($count > 0){
while($row=$results->fetch_assoc()){
echo $row['ingredName'];
echo $row['name'] . "<br />";
$output="ff";
}
}
}
?>
Line numbers would help, to see if line 15 is the assignment to $results, or if line 15 is the $results->num_rows
I'm also assuming you have a $db_conx->connect command somewhere in your code, to open the database connection before running the query?
Your SQL query is invalid: there is no such column as ingred.name available in the WHERE clause, because you have renamed that table as b.
There is no reason to rename your tables (using AS ...) in this query. Leave that clause out. Then add a join condition (e.g, ... JOIN ingred ON (...) — omitting this will make the query return every row from main_meal.
Additionally, there is probably a SQL injection vulnerability in your code, because you are interpolating the contents of the (likely unfiltered) $searchq variable into the query. Use a query placeholder for the argument to LIKE.
Related
Basically, I am seeking to know if there is a better way to accomplish this specific task.
Basically, what happens is I query the db for a list of "project needs" -- These are each uniquer and only appear once.
Then, I search another table to find out how many members have the required "skills - which are directly correlated to the project needs".
I accomplished exactly what I was trying to do by running a second query and then inserting them into an array like this:
function countEachSkill(){
$return = array();
$query = "SELECT DISTINCT SKILL_ID, SKILL_NAME FROM PROJECT_NEEDS";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)){
$query = "SELECT COUNT(*) as COUNT FROM MEMBER_SKILLS WHERE SKILL_ID = '".$row['NEED_ID']."'";
$cResult = mysql_query($query);
$cRow = mysql_fetch_assoc($cResult);
$return[$row['SKILL_ID']]['Count'] = $cRow['COUNT'];
$return[$row['SKILL_ID']]['Name'] = $row['SKILL_NAME'];
}
arsort($return);
return $return;
}
But I feel like there has to be a better way (perhaps using some kind of join?) that would return this in a result set to avoid using the array.
Thanks in advance.
PS. I know mysql_ is depreciated. It is not my choice on which to use.
SELECT P.SKILL_ID, P.SKILL_NAME, COUNT(M.SKILL_ID) as COUNT FROM PROJECT_NEEDS P INNER JOIN MEMBER_SKILLS M
ON P.SKILL_ID=M.SKILL_ID
GROUP BY P.SKILL_ID, P.SKILL_NAME
I've adjusted Nriddens answer to accomodate for the select distinct, Im under the belief that his adjustment would be ok given SKILL_ID is a primary key
function countEachSkill(){
$return = array();
$query = "
SELECT
COUNT(*) AS COUNT,
PROJECT_NEEDS.SKILL_NAME,
PROJECT_NEEDS.SKILL_ID
FROM
(SELECT DISTINCT
SKILL_ID, SKILL_NAME
FROM
PROJECT_NEEDS) AS PROJECT_NEEDS
INNER JOIN
MEMBER_SKILLS
ON
MEMBER_SKILLS.SKILL_ID = PROJECT_NEEDS.SKILL_ID
GROUP BY PROJECT_NEEDS.SKILL_ID";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)){
$return[$row['SKILL_ID']]['Count'] = $row['COUNT'];
$return[$row['SKILL_ID']]['Name'] = $row['SKILL_NAME'];
}
arsort($return);
return $return;
I am subquerying on the select distinct because I dont believe you have a dedicated skills table with an auto inc primary key, if that was there I wouldn't be using a subquery.
Can you test this query
select project_needs.*,count(members_skills.*) as count from project_needs
inner join members_skills
on members_skills.skill_id=project_needs.skill_id Group by project_needs.skill_name, project_needs.skill_id
I was wondering if someone can help me with my problem that is as follows:
I want to pull once posts.text and uids which belongs to that posts.text but when I execute the code below it does this: eg. there are 4 uids that belongs to the post so I get the posts.text four times instead of once.
$query = mysqli_query($con,
"SELECT posts.text, relationships.uidb
FROM posts
LEFT JOIN relationships
ON posts.uid=relationships.uida
LIMIT 10");
if(mysqli_num_rows($query) > 0){
while($row = mysqli_fetch_assoc($query)){
echo $row['text']." ".$row['uidb']."<br>";
}
}
I would really appreciate any help.
Thanks is advance.
Peter
Update:
Desired output would be like this:
postsArray[0]->text = //post text
postsArray[1]->text = //another post text
postsArray[0]->uids[0] = //approved uid for first post
postsArray[0]->uids[1] = //another approved uid for first post
now it outputs this:
text 10
text 15
text 12
and I want this:
text 10, 15, 12
One way is to use Mysql's GROUP_CONCAT which provides comma separated values list for each group i.e (p.uid)
$query = mysqli_query($con,
"SELECT p.text, GROUP_CONCAT(r.uidb SEPARATOR ', ') uidbs
FROM posts p
LEFT JOIN relationships r
ON p.uid=r.uida
GROUP BY p.uid
LIMIT 10");
if (mysqli_num_rows($query) > 0) {
while ($row = mysqli_fetch_assoc($query)) {
echo $row['text'].' '.$row['uidbs'];
/*$uidbs= explode($row['uidbs'],',');
foreach ($uidbs as $key => $val) {
echo $val.' ';
}*/
echo '</br>';
}
}
GROUP_CONCAT
According to docs The result is truncated to the maximum length that
is given by the group_concat_max_len system variable, which has a
default value of 1024. The value can be set higher, although the
effective maximum length of the return value is constrained by the
value of max_allowed_packet.
Maybe this might work for you:
$query = mysqli_query($con,
"SELECT posts.text, relationships.uidb
FROM posts
LEFT JOIN relationships
ON posts.uid=relationships.uida
GROUP BY posts.uid
LIMIT 10");
if(mysqli_num_rows($query) > 0){
while($row = mysqli_fetch_assoc($query)){
echo $row['text']." ".$row['uidb']."<br>";
}
}
SELECT posts.text, relationships.uidb
FROM posts
LEFT JOIN relationships
ON posts.uid=relationships.uida
GROUP BY posts.primary_key_of_your_post
LIMIT 10
You should call 2 queries. In your first query, call the text, and then call uids.
You should not write complex queries because this will make your business more complex and you will not maintain your code in future.
I have two table records in my database which look like this:
Table 1 with the column 1:
topic_id name
21 my computer
table 2 with columns as follows:
reply_id topic_id message
1 21 blabla
2 21 blue
In which the topic_id column in the table 2 is the foreign key of the table 1
I wanted to echo all replies in the table 2 along with the topic name (#21) in the table 1. So, I made the query like this
$q="SELECT name, message
FROM table1
LEFT JOIN table2
ON table1.topic_id = table2.topic_id
";
However, the result/ output returns the topic's name and ONLY ONE reply, but not 2 (or all) as expected. Did I miss something?
I used LEFT JOIN because some topics are still waiting for replies. In case that there is not any reply, the topic's name is still printed in browsers.
I also tried adding
GROUP BY table1.topic_id
but still NO LUCK!
Can you help? Thanks
EDIT: To clarify the question I add the php code to fetch records as follows:
As you know, The name needs to be printed only once. So, I code like this:
$tid = FALSE;
if(isset($_GET['qid']) && filter_var($_GET['qid'], FILTER_VALIDATE_INT, array('min_range'=>1) ) ){
// create the shorthand of the question ID:
$tid = $_GET['tid'];
// run query ($q) as shown above
$r = mysqli_query($dbc, $q) or die("MySQL error: " . mysqli_error($dbc) . "<hr>\nQuery: $q");
if (!(mysqli_num_rows($r) > 0) ){
$tid = FALSE; // valid topic id
}
}//isset($_GET['qid']
if ($tid) { //OK
$printtopic = FALSE; // flag variable to print topic once
while($content = mysqli_fetch_array($r, MYSQLI_ASSOC)){
if (!$printtopic) {
echo $content['name'];
$printtopic= TRUE;
}
}
} // end of $tid
// Print the messages if any:
echo $content['message'];
Try this with inner join
$q="SELECT name, message
FROM table1
INNER JOIN table2
ON table1.topic_id = table2.topic_id";
Try:
$q="SELECT table2.reply_id, table1.name, table2.message
FROM table2
LEFT JOIN table1
ON table1.topic_id = table2.topic_id
";
After struggling with this issue, I can find out that the problem is that I had to change the query to INNER JOIN and add the WHERE clause like this:
WHERE table2.reply_id = {the given topic_id}
Then it works well!
Sorry to disturb you all!
I'm building a search function for my site, however the MySQl query won't read the PHP variables, and I don't mean errors, it just seems to think they're NULL.
My current code is:
$conn = mysql_connect('localhost', 'root', '');
mysql_select_db('library', $conn);
$sql = "SELECT * FROM Books";
if($_POST['find']!="")
{
if($_POST['field'] == "Books")
{
$sql = "SELECT *
FROM Books
JOIN bookauthor ON books.BookID = bookauthor.BookID
JOIN authors ON bookauthor.AuthorID = authors.AuthorID
WHERE books.BookName LIKE '%''".($_POST['find'])."''%'
GROUP BY books.BookName
ORDER BY authors.AuthorID";
}
else if ($_POST['field'] == "Authors")
{
$sql = "SELECT *
FROM Books
JOIN bookauthor ON books.BookID = bookauthor.BookID
JOIN authors ON bookauthor.AuthorID = authors.AuthorID
WHERE authors.Forename LIKE '%J.%'
AND authors.Surname LIKE '%%'
GROUP BY books.BookName
ORDER BY authors.AuthorID";
}
}
$result = mysql_query($sql, $conn) or die("Can't run query");
$loopnumber = 1;
if (mysql_num_rows($result) ==0 ){echo "No Results have been found";}
The POST variable does contain data as I've tested by echo'ing it, however my site just gives the "No Results have been found" message meaning the query retuned no results.
Even if I pass the POST into a normal variable I get the same results.
However if I remove the "LIKE '%%'" and have it look for and exact match from typing in the search on the site it works fine.
Edit: Hmmmm, just made it so I pass the POST into a variable like so..
$searchf = "%".$_POST['find']."%";
and having that variable in the WHERE LIKE makes it work, now I'm just curious as to why it doesn't work the other way.
I seems to love quotation marks too much, and should go to bed.
Well first of all, I am guessing you are getting a MySQL syntax error when trying to execute that first query. This line:
WHERE books.BookName LIKE '%''".($_POST['find'])."''%'
Should be
WHERE books.BookName LIKE '%".$_POST['find']."%'
Because right now you are getting
WHERE books.BookName LIKE '%''ABC''%'
when you should be getting
WHERE books.BookName LIKE '%ABC%'
I don't admit to understand what you are doing with your second query, which just hard codes and has %% as one of the search criteria, which is, in essence meaningless.
Its in your LIKE expression. If in $_POST['find'] the value is LOTR the query would be
WHERE books.BookName LIKE '%''LOTR''%'
and the resault would be empty. Just remove the double ' and it should be work.
Try this way:
$sql = "SELECT *
FROM Books
JOIN bookauthor ON books.BookID = bookauthor.BookID
JOIN authors ON bookauthor.AuthorID = authors.AuthorID
WHERE books.BookName LIKE '%".$_POST['find']."%'
GROUP BY books.BookName
ORDER BY authors.AuthorID";
It should be work
use this, worked for me:
$query_casenumber = "SELECT * FROM pv_metrics WHERE casenumber='$keyword' OR age='$keyword' OR product='$keyword' OR eventpreferredterm='$keyword' OR patientoutcome='$keyword' OR eventsystemclassSOC='$keyword' OR asdeterminedlistedness='$keyword' OR narrative LIKE '%".$_POST['keyword']."%' ";
I would like to add a value to each row that I get from my query depending on if a row exist in another table. Is there a smart way to achieve this?
This is the code I have:
$sth = mysql_query("SELECT tbl_subApp2Tag.*, tbl_tag.* FROM tbl_subApp2Tag LEFT JOIN tbl_tag ON tbl_subApp2Tag.tag_id = tbl_tag.id WHERE tbl_subApp2Tag.subApp_id = '".$sub."' ORDER BY tbl_tag.name ASC");
if(!$sth) echo "Error in query: ".mysql_error();
while($r = mysql_fetch_assoc($sth)) {
$query = "SELECT * FROM tbl_userDevice2Tag WHERE tag_id='".$r['id']."' AND userDevice_id='".$user."'";
$result = mysql_query($query) or die(mysql_error());
if (mysql_num_rows($result)) {
$r['relation'] = true;
$rows[] = $r; //Add 'relation' => true to this row
} else {
$r['relation'] = false;
$rows[] = $r; //Add 'relation' => false to this row
}
}
print json_encode($rows);
Where the //Add ... is, is where I would like to insert the extra value. Any suggestions of how I can do this?
I'm still a beginner in PHP so if there are anything else that I have missed please tell me.
EDIT: Second query was from the wrong table. This is the correct one.
Edited Edited below query to reflect new information because I don't like leaving things half-done.
$sth = mysql_query("
SELECT
tbl_subApp2Tag.*,
tbl_tag.*,
ISNULL(tbl_userDevice2Tag.userDevice_id) AS relation
FROM tbl_subApp2Tag
LEFT JOIN tbl_tag
ON tbl_tag.id = tbl_subApp2Tag.tag_id
LEFT JOIN tbl_userDevice2Tag
ON tbl_userDevice2Tag.tag_id = tbl_tag.id
AND tbl_userDevice2Tag.userDevice_id = '".$user."'
WHERE tbl_subApp2Tag.subApp_id = '".$sub."'
ORDER BY tbl_tag.name ASC
");
Though the above feels like the LEFT JOIN on tbl_tag is the wrong way around, but it's hard to tell as you are vague on your eventual aim. For example, if I was to assume the following
Tags will always exist
subApp2Tag will always exist
You want to know if a record in tbl_userDevice2Tag matches the above
Then I would do the following instead. The INNER JOIN means that it won't worry about records in tbl_tag that are not on the requested subApp_id which in turn will limit the other joins.
$sth = mysql_query("
SELECT
tbl_subApp2Tag.*,
tbl_tag.*,
ISNULL(tbl_userDevice2Tag.userDevice_id) AS relation
FROM tbl_tag
INNER JOIN tbl_subApp2Tag
ON tbl_subApp2Tag.tag_id = tbl_tag.id
AND tbl_subApp2Tag.subApp_id = '".$sub."'
LEFT JOIN tbl_userDevice2Tag
ON tbl_userDevice2Tag.tag_id = tbl_tag.id
AND tbl_userDevice2Tag.userDevice_id = '".$user."'
ORDER BY tbl_tag.name ASC
");
you have to do all the job in a single query.
Why can't you just $r['append'] = "value"; before adding $r to the array?