I am building a recipe database with some of my friends and for that we need our users to be able to search within our site. Our database consists of 3 tables:
recipes - recipe_id (primary key), recipe_name
ingredients - ingredient_id (primary key), ingredient_name
recipe_ingredients - ingredient_id (foreign key), recipe_id (foreign key)
We want to be able to search the recipe_ingredients for a recipe or ingredient name and have our site show every ingredient connected to that recipe or every recipe connected to that ingredient. And so we made this query:
select ingredient_name, recipe_name, recipe_ingredients.*
from recipe_ingredients
inner join ingredients inner join recipes
on recipe_ingredients.ingredient_id = ingredients.ingredient_id
and recipe_ingredients.recipe_id = recipes.recipe_id
WHERE ingredient_name = 'Brød';
Which works fine for us. However, putting it into our search function in php, it gives 'There were no search results!' back every single time no matter what we searched. Here is the code. Would someone point out the mistake we made?
$output = '';
if (isset($_POST['work'])) {
$searchq = $_POST['work'];
$searchq = preg_replace("#[^0-9a-z]#i","",$searchq);
$query = mysql_query
("select ingredient_name, recipe_name, recipe_ingredients.*
from recipe_ingredients
inner join ingredients inner join recipes
on recipe_ingredients.ingredient_id = ingredients.ingredient_id
and recipe_ingredients.recipe_id = recipes.recipe_id
WHERE ingredient_name LIKE '%searchq%' or recipe_name LIKE '%searchq%'")
or die ("Could not search");
$count = mysql_num_rows($query);
if($count == 0){
$output = 'There were no search results!';
}
else{
while ($row = mysql_fetch_array($query)) {
$recipe = $row[recipe_name];
$ingredient = $row[ingredient_name];
$id = $row[ingredient_id];
$output .= '<div>'.$recipe.' '.$ingredient.'</div>';
}
}
}
We don't understand why it won't work.
You can try the following. It uses mysqli_* functions and a better structure for the query joins.
$connection = mysqli_connect('localhost', 'root', 'your_password', 'your_database');
mysqli_set_charset($connection, 'utf8');
if (!$connection) {
die("Database connection failed: " . mysqli_error());
}
$output = '';
if (isset($_POST['work'])) {
$searchq = $_POST['work'];
$searchq = preg_replace("#[^0-9a-z]#i", "", $searchq);
$sql = "
SELECT ingredient_name, recipe_name, recipe_ingredients.*
FROM recipe_ingredients
INNER JOIN ingredients
ON recipe_ingredients.ingredient_id = ingredients.ingredient_id
INNER JOIN recipes
ON recipe_ingredients.recipe_id = recipes.recipe_id
WHERE ingredient_name LIKE '%$searchq%' or recipe_name LIKE '%$searchq%'";
$result = mysqli_query($connection, $sql);
if (!$result) {
die("SQL Error: " . mysqli_error($connection);
}
$count = mysqli_num_rows($result);
if ($count == 0) {
$output = 'There were no search results!';
} else {
while ($row = mysqli_fetch_array($result)) {
$recipe = $row[recipe_name];
$ingredient = $row[ingredient_name];
$id = $row[ingredient_id];
$output .= '<div>'.$recipe.' '.$ingredient.'</div>';
}
}
}
First - it depends on what version of PHP you are using, as Jens pointed out mysql_* has been deprecated.
Second - it does not appear that you are connecting to your database. You have to connect to your database first, then execute your query.
Check out this example on PHP's website, it should help you out a lot.
Good luck!
It seems like you re searching for "searchq" all the time and you probably dont have a recipe by that name and I would advise agajnst mysql_* funcs
$output = '';
if (isset($_POST['work'])) {
$searchq = $_POST['work'];
$searchq = preg_replace("#[^0-9a-z]#
i","",$searchq);
$query = mysql_query
("select ingredient_name, recipe_name, recipe_ingredients.*
from recipe_ingredients
inner join ingredients inner join recipes
on recipe_ingredients.ingredient_id = ingredients.ingredient_id
and recipe_ingredients.recipe_id = recipes.recipe_id
WHERE ingredient_name LIKE '%
$searchq%' or recipe_name LIKE '%
$searchq%'")
Related
I am really struggling to understand what is wrong with my query. When I use var_dump($sqli); it just echos out the entire query without any data in it.
I want to create a query so when a user searches for a city the returned search result would be the attractions associated with that city. I realise that there is a few errors with my code, however if I get the query completed I will go from there and debug the rest of the code. If anyone has any ideas as to why my query isn't working I would greatly appreciate them.
require_once('config1.php');
error_reporting(E_ALL);
$output = '';
if(isset($_POST['search'])){
$searchq = $_POST['search'];
$sqli = 'SELECT attraction_name, lat, long, cost FROM zz_attractions WHERE city_id IN SELECT city_id FROM zz_city WHERE city_name LIKE %searchq%' or die("could not search");
var_dump($sqli);
$result = mysqli_query($conn, $sqli);
$count = mysqli_num_rows($result);
if ($count == 0) {
$output = 'there was no search results';
} else {
while ($row = mysql_fetch_array($sqli)) {
$attraction_name = $row['attractionname'];
$lat = $row['latitude'];
$long = $row['longitude'];
$cost = $row['cost'];
$output .= '<div>'.$attraction_name.' '.$lat.' '.$long.' '.$cost.'</div>';
}
}
}
Your current query fails because you need the parentheses shown here:
SELECT attraction_name, lat, long, cost
FROM zz_attractions
WHERE city_id IN (SELECT city_id
FROM zz_city
WHERE city_name
LIKE '%searchq%')
But a better way to do it would be an inner join:
SELECT a.attraction_name, a.lat, a.long, a.cost
FROM zz_attractions a
INNER JOIN zz_city c ON a.city_id = c.city_id
WHERE c.city_name LIKE '%searchq%'
----
just an observation, nothing more...
Never quite understood why PHP coders tend to have every SQL query as a single row
$query = '
SELECT a.attraction_name, a.lat, a.long, a.cost
FROM zz_attractions a
INNER JOIN zz_city c ON a.city_id = c.city_id
WHERE c.city_name LIKE %searchq%
';
echo $query;
i have a project to build a CMS. We were giving a few functions.. on is below. I would like someone to explain to me what the 'p', 'ca', and 'cm' mean/stand for?
function getAllPosts() {
global $db;
$sql = "SELECT p.*, ca.catName, COUNT(commentID) as numComments
FROM posts p
LEFT JOIN categorys ca USING (categoryID)
LEFT JOIN comments cm USING (postID)
";
if ($_GET['catID'] != ''){
$catID = (int)$_GET['catID'];
$sql .= "WHERE categoryID = $catID ";
}
$sql .= "GROUP BY postID
ORDER BY postDate DESC";
$qry = mysqli_query($db, $sql);
$result = array();
while ($row = mysqli_fetch_assoc($qry)) {
$result[] = $row;
}
if (count($result) > 0) {
return $result;
}
return false;
}
They are a shorter way to write a query without using the whole table names. (table alias)
E.g. SELECT a.name, a.surname FROM very_long_name_of_my_table [AS] a
instead of
SELECT very_long_name_of_my_table.name, very_long_name_of_my_table.surname FROM very_long_name_of_my_table
SQL aliases are used to give a database table, or a column in a table, a temporary name.
Basically aliases are created to make column names more readable.
for more visit: http://www.w3schools.com/sql/sql_alias.asp
I am using the following tables:
artists
related_artists
The idea is when I enter an artist's page with an artist_id I can use that id to load related artists. The following code works, but how do I put it in a single query? I can't figure it out.
To connect related_artists with artists I created the following code:
$sql = "SELECT related_artist_id FROM related_artists WHERE artist_id = 1";
$res = mysqli_query($db, $sql);
if (!$res) {
echo "Er is een fout opgetreden.";
exit;
} else {
while ($row = mysqli_fetch_array($res)) {
$query = 'SELECT * FROM artists WHERE artist_id = '.$row["related_artist_id"];
print_r($query."<br />\n");
$result = mysqli_query($db, $query);
if ($result) {
while ($test = mysqli_fetch_array($result)) {
echo $test["lastName"]."<br />\n";
}
} else {
echo "It doesn't work";
exit;
}
}
}
You can just try :
select *
from artists
where artist_id in (
select related_artist_id
from related_artists
WHERE artist_id = 1
);
You can use a LEFT JOIN, try this:
SELECT b.*
FROM related_artist a
LEFT JOIN artists b
USING(artist_id)
WHERE a.artist_id = 1
Should return * from artists, where I aliased artists as b and related_artist as a.
Didn't test, does it work for you / return the expected result?
SELECT * FROM artists where artists.arist_id = 1
INNER JOIN related_artist ON related_artist.artist_id = artists.artist_id
This provides a join on the artist_id columns of both tables, having artist_id = 1. I'm not sure if you need an Inner or a Left join
I currently have this query with an array that outputs the variables within using a dynamic input in my form (term), this creates a Dynamic Search with auto complete to fill in all of the details for a product.
$return_arr = array();
$param = $_GET["term"];
$fetch = mysql_query("SELECT * FROM crd_jshopping_products WHERE `name_en-GB` REGEXP '^$param'");
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
//$row_array['category_id'] = $row ['category_id'];
$row_array['product_id'] = $row['product_id'];
$row_array['product_names'] = $row['name_en-GB'];
$row_array['jshop_code_prod'] = $row['product_ean'];
$row_array['_ext_price_html'] = number_format($row['product_price'],2);
if (!empty($row['product_thumb_image']) AND isset($row['product_thumb_image'])){
$row_array['image'] = $row['product_thumb_image'];
}else {
$row_array['image'] = 'noimage.gif';
}
array_push( $return_arr, $row_array);
}
mysql_close($conn);
echo json_encode($return_arr);
Unfortunately I also need to get the category_id which is not in the same table, I have tried to modify my query as such, but to no avail:
$fetch = mysql_query("SELECT * FROM crd_jshopping_products WHERE `name_en-GB` REGEXP '^$param' AND `crd_jshopping_products_to_categories` = `product_id` ");
What step am I missing here ? The product_id's match in both tables?
try this query instead and try to understand what I have written in it:
$fetch = mysql_query("
SELECT
p.*,
c.category_id
FROM
crd_jshopping_products as p
INNER JOIN crd_jshopping_products_to_categories as c
ON p.product_id = c.product_id
WHERE
`p.name_en-GB` REGEXP '^$param'
");
This means:
SELECT:
Give me everything from p and the category_id from c.
FROM:
Do this from rows in the tables crd_jshopping_products (referred to as p) and crd_jshopping_products_to_categories (referred to as c), where the rows match on the count of p.product_id is the same as c.product_id.
WHERE:
Only return the rows where p.name_en-GB REGEXP '^$param'.
<?php
$query1 = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X";
$query2 = "CREATE VIEW previous_rankings AS SELECT rank FROM main_table WHERE date = date_sub('X', INTERVAL 1 MONTH)";
$query3 = "CREATE VIEW final_output AS SELECT current_rankings.player, current_rankings.rank as current_rank LEFT JOIN previous_rankings.rank as prev_rank
ON (current_rankings.player = previous_rankings.player)";
$query4 = "SELECT *, #rank_change = prev_rank - current_rank as rank_change from final_output";
$result = mysql_query($query4) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
echo $row['player']. $row['current_rank']. $row['prev_rank']. $row['rank_change'];
}
?>
All the queries work independently but am really struggling putting all the pieces together in one single result so I can use it with mysql_fetch_array.
I've tried to create views as well as temporary tables but each time it either says table does not exist or return an empty fetch array loop...logic is there but syntax is messed up I think as it's the 1st time I had to deal with multiple queries I need to merge all together. Looking forward to some support. Many thanks.
Thanks to php.net I've come up with a solution : you have to use (mysqli_multi_query($link, $query)) to run multiple concatenated queries.
/* create sql connection*/
$link = mysqli_connect("server", "user", "password", "database");
$query = "SQL STATEMENTS;"; /* first query : Notice the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS;"; /* Notice the dot before = and the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS;"; /* Notice the dot before = and the 2 semicolons at the end ! */
$query .= "SQL STATEMENTS"; /* last query : Notice the dot before = at the end ! */
/* Execute queries */
if (mysqli_multi_query($link, $query)) {
do {
/* store first result set */
if ($result = mysqli_store_result($link)) {
while ($row = mysqli_fetch_array($result))
/* print your results */
{
echo $row['column1'];
echo $row['column2'];
}
mysqli_free_result($result);
}
} while (mysqli_next_result($link));
}
EDIT - The solution above works if you really want to do one big query but it's also possible to execute as many queries as you wish and execute them separately.
$query1 = "Create temporary table A select c1 from t1";
$result1 = mysqli_query($link, $query1) or die(mysqli_error());
$query2 = "select c1 from A";
$result2 = mysqli_query($link, $query2) or die(mysqli_error());
while($row = mysqli_fetch_array($result2)) {
echo $row['c1'];
}
It seems you are not executing $query1 - $query3. You have just skipped to $query4 which won't work if the others have not been executed first.
Also
$query4 = "SELECT *, #rank_change = prev_rank - current_rank as rank_change from final_output";
should probably be
$query4 = "SELECT *, #rank_change := prev_rank - current_rank as rank_change from final_output";
or else the value of rank_change will just be a boolean, true if #rank_change is equal to (prev_rank - current_rank), false if it is not. But do you need #rank_change at all? Will you use it in a subsequent query? Maybe you can remove it altogether.
Even better, you could just combine all the queries into one like this:
SELECT
curr.player,
curr.rank AS current_rank,
#rank_change := prev.rank - curr.rank AS rank_change
FROM
main_table AS curr
LEFT JOIN main_table AS prev
ON curr.player = prev.player
WHERE
curr.date = X
AND prev.date = date_sub('X', INTERVAL 1 MONTH)
You should concatenate them:
<?php
$query = "CREATE VIEW current_rankings AS SELECT * FROM main_table WHERE date = X";
$query .= " CREATE VIEW previous_rankings AS SELECT rank FROM main_table WHERE date = date_sub('X', INTERVAL 1 MONTH)";
$query .= " CREATE VIEW final_output AS SELECT current_rankings.player, current_rankings.rank as current_rank LEFT JOIN previous_rankings.rank as prev_rank
ON (current_rankings.player = previous_rankings.player)";
$query .= " SELECT *, #rank_change = prev_rank - current_rank as rank_change from final_output";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
echo $row['player']. $row['current_rank']. $row['prev_rank']. $row['rank_change'];
}
?>