PHP / MYSQL Do I Need to SQL Join? - php

I know this may be a stupid question but I am not very experienced with SQL Joins and I don't want to do it without fully knowing that it is the right thing to do.
I have created a recipe site which have different categories like bread, biscuits, cake etc. these are all in the category table of the database. I have recipes in the recipe table.
The problem I am facing is, on the category page, since each category has its own ID I created one page where each categories redirect to and used this code
<a href="index.php?p=selected&id=<?php echo $recipe['cat_id']; ?>">
This one page features different categories based on the ID, the id is changed in the url so for the bread category it would look like this:
index.php?p=selected&id=1
So, since there is one page for each category I want it to display the recipes, I used this code:
$query = "SELECT * FROM recipes ORDER BY recipe_id ASC";
but this displays every recipe in the database, what I want is for it to display the recipe based on the category it is in like below:
$query = "SELECT * FROM recipes WHERE cat_id = :id ORDER BY recipe_id ASC";
The cat_id is part of the category table, so do I need to join this table to the recipe table to make it work?
Be sure to tell me if I have missed something,
Thank you for your time.

yes you have missed something
must add column cat_id in recipes table which equal cat_id in category table
when you add item in recipes table
and then it simple
$query = "SELECT * FROM recipes
WHERE recipes.cat_id = :id";
or
$id = intval($_GET['id']);
$query = "SELECT * FROM recipes
WHERE recipes.cat_id = $id";

If one recipe one category then,
SELECT * FROM recipes inner join category
on category.id=recipe.cat_id
where cat_id = :id ORDER BY recipe_id ASC";
If one cateory many recipes then
SELECT * FROM recipes leftjoin category
on category.id=recipe.cat_id
where cat_id = :id ORDER BY recipe_id ASC";

Related

How to connect two MySQL tables

I have in my MySqli Database a table called "products".
Products TABLE
product_id | INT primary KEY
product_name | VARCHAR(50)
product_price | float
From PHP i enter rows in the table products like this way:
mysqli_query($con,"INSERT INTO products (product_id,product_name,product_price) VALUES
('$product_id','$product_name','$price')");
So far all work perfectly. Now i want to have a second table called "category", this table will include all the possible categories that a product can have
The Category table must have a category_id and a category_name as columns
Category TABLE
category_id | INT primary KEY
category_name | VARCHAR(50)
I'm trying to figured out a way to connect a product with the category in my PHP file
for example:
$get=mysqli_query($con, "SELECT * FROM `category`");
while ($row = mysqli_fetch_assoc($get)) {
echo $row['category_name']; //...here show all the categories
//...
//.. pick the category that the product belong
$category_Selected= .....;
}?>
..... And make the connection (with INSERT? or something) between product and category
Ι want to be able when i'm doing a search at the product table, (for a product X) to show also and the category that it belongs (so far i can show the Product_id, product_name and product_price)
Thank you
You want to join your Tables.
Take a look here:
Join Tables - w3schools
MySQL Join Tables Syntax
If a product can be only in one category then you can add a category_id in your Products table.
I would suggest a third table the:
Product_category
id | PK
product_id | Foreign key to Products.id
category_id| Foreign key to Categories.id
Now every time you insert a product you need to get also the id of your category and do an insert statement to Product_category table.
To retrieve your data you could do something like this:
$get=mysqli_query($con, "SELECT * FROM `category`");
while ($row = mysqli_fetch_assoc($get)) {
echo $row['category_name']; //...here show all the categories
$products=mysqli_query($con, "SELECT * FROM `Products` WHERE id IN
(SELECT product_id from Product_category WHERE category_id= ".(int)$row['category_id'] . ")");
while ($product = mysqli_fetch_assoc($products)) {
echo $product["product_name"] . ", " . $product["product_price"];
}
}
The above statement is as example, you could use JOIN and prepared statements.
If you choose to alter the product table and add the category_id there, then
the example code would be this:
$get=mysqli_query($con, "SELECT * FROM `category`");
while ($row = mysqli_fetch_assoc($get)) {
echo $row['category_name']; //...here show all the categories
$products=mysqli_query($con, "SELECT * FROM `Products` WHERE category_id = " . (int) $row["category_id"]);
while ($product = mysqli_fetch_assoc($products)) {
echo $product["product_name"] . ", " . $product["product_price"];
}
}
As it is, your database does not allow you to represent the relationshup between categories and products. You would need to alter your design.
I can imagine that one product belongs to a category, and that one category can have several products.
If so, I would recommend creating a categories table to store the categories, with (at least) columns category_id and category_name.
CREATE TABLE categories (
category_id INT PRIMARY KEY AUTO_INCREMENT,
category_name VARCHAR(100)
);
In the product table, you want to add a column in the products table that stores a reference to the id of the corresponding category :
ALTER TABLE products ADD
COLUMN category_id INT
FOREIGN KEY (category_fk) REFERENCES categories(id) ON DELETE CASCADE;
With this modified database design, when you insert into products, you pass the reference of the category (one could expect that the user of your application will select it from some kind of drop down list when creating the product) :
INSERT INTO products (product_id, product_name, product_price, category_id)
VALUES ( :product_id, :product_name, :price, :category_id );
And when you want to display a product along with its category name, you can use a simple JOIN :
SELECT p.*, c.category_name
FROM products p
INNER JOIN categories c ON c.category_id = p.category_id
WHERE p.produt_id = :product_id
PS : never pass POSTed values to your SQL queries like this : this exposes you to SQL injection (and also makes your queries less readable and efficient). I changed the queries to use named parameters.

returning data from table using category_id from a category table from mysql using php

Hi everyone this is my first question here and i'll be very grateful if you could help me.
I have a table like this in mysql
//table items
id | item_name | description | link | category_id | is_active
And i have another table like this
//table categories
id category_name | cat_description | is_active
I want to get all the data in category_name and get all the content from item_name if is_active column is on, and also if category is_active column is on.
I was trying to make a function that would retrieve all that data with html content and just if certain conditions are true.
My function is something like this:
function getCatAndItems(){
include "conn.php";
$petition = mysqli_query($conn,"SELECT * FROM items,categories WHERE is_active=1");
while ($row = mysqli_fetch_array($petition)) {
$filename = $row['nombre'];
$url = $row['url_document'];
echo "<a href=../docs/files/$url'><li> ".$filename."</li></a>";
}
}
My goal is to bring the categories and if the categories are active and if the items table in the category_id is the same as the category id and is_active it will bring me also the data in the items table that share the same number.
I hope you understand me and hope you could help me, thank's
You can get using JOIN
SELECT items.name, items.description, items.link, categories.category_name, categories.cat_description
FROM categories
JOIN items
ON categories.id = items.category_id
WHERE categories.is_active = 1
AND items.is_active = 1;
Here is your query :
select i.id,i.item_name,i.description,i.link,i.category_id,i.is_active,c.category_name
from items as i left join categories as c on i.category_id=c.id where
i.is_active=1 and c.is_active=1;
A simple inner join between these two tables would do the job done.
SELECT
items.name,
items.description,
items.link,
categories.category_name,
categories.cat_description
FROM categories
INNER JOIN items ON categories.id = items.category_id
WHERE categories.is_active = 1
AND items.is_active = 1

SELECT * FROM tbl WHERE col1=$var1 and col2=$var2 and col3=$var3

Music Database Site:
I have a table named ps_albums with columns: artist, album, genre_id, and so on.
I also have a second table named ps_users with the following column: user_id, date_joined, fave_genre_1, fave_genre_2, fav_genre_3 and other.
My overall goal is to display only the genres of music that a user selects for the top 3 favorite selections.
I am able to INSERT the genre_id of all 3 favorite genre selections into ps_profiles which hold this info. Now I need to be able to pull the 3 genres_id's and display only them instead off all genres by default.
So by default SELECT * FROM ps_albums ORDER by DESC;
Thus displaying ALL albums on the front page.
Now, when that user clicks 'My Favorite Genres' I do this...
$query= "SELECT * FROM `ps_profiles` WHERE `user_id`= $user_id";
$row = #mysql_fetch_object(#mysql_query($query));
$genre1 = $row->fav_genre_1;
$genre2 = $row->fav_genre_2;
$genre3 = $row->fav_genre_3;
I want to be able to display all records from ps_albums according to the 3 favorite selections from ps_profiles.
How would I setup the select statement?
SELECT * FROM ps_albums WHERE genre=$genre1 AND genre=$genre2 AND genre=$genre3
How would I go about this? There are more then 10 genres but I only want to show the ones selected as favorites from the 3 columns. Hopes this clarifys a bit more.
SELECT * FROM ps_albums WHERE genre in ($genre1,$genre2,$genre3)
You could use either OR's or IN() to match a column value with multiple possible value.
For example:
SELECT * FROM t WHERE a=1 OR a=2 OR a=3;
SELECT * FROM t WHERE a IN(1,2,3);
So for your case, it could look something like this:
$query = "SELECT * FROM ps_albums WHERE genre IN('$genre1', '$genre2', '$genre3')";
I added quotes in the query, I'm assuming genre's are strings?

Displaying alternate column when using foreign keys

I have an issue regarding PHP, MySql and foreign keys. I understand foreign keys and have a relationship between two tables in place as described:
Let's say I have 2 tables: 'vehicles' and 'manufacturers'.
Each row in the 'vehicles' table includes a manufacturerId column which is a foreign key relating to the 'manufacturers' table. This is set up nicely, in PhpMyAdmin when I insert a new row into the 'vehicles' table the manufacturerId column has a drop-down menu with the manufacturerId's listed as options. Very nice.
BUT: In my application, of course, I don't want the user to have to know (or have to guess) what the correct number for 'Ford' or 'BMW' is when they add a new vehicle, I want them to be able to choose the manufacturer by name.
But how does the application know the manufacturer names based on the manufacturerId? How does the application know there is a relationship between the 2 tables? Am I supposed to hard-code the relationship in the application? Am I supposed to modify all my queries to have a JOIN between the 2 tables? Or hard-code a query to get a list of manufacturers every time I want to display a drop-down of manufacturers?
Is there a way for the application to know about relationships between tables and be able to display data from a text column instead of the int column used as the ID?
Assuming your 2 table are structured like this:
VEHICLES
id
manufacturerId
vehicleName
MANUFACTURERS
id
manufacturerName
You would create your vehicle manufacturer select menu for users by querying the database like this:
// query the database
$q = 'SELECT id, manufacturerName FROM manufacturers';
$r = mysqli_query($link, $q);
// display a select menu using id and manufacturerName
echo '<select name="manufacturer">';
while($row = mysqli_fetch_assoc($r)) {
echo '<option value="'.$row['id'].'">'.$row['manufacturerName'].'</option>';
}
echo '</select>';
To use the post data from that menu to add a vehicle & manufacturer id to your vehicles table:
$q = "INSERT INTO vehicles (manufacturerId, vehicleName) VALUES ({$_POST['manufacturer']}, '{$_POST['vehicleName']}')";
mysqli_query($link, $q);
Finally, if you wish to select the vehicle name and manufacturer in the same query, you would join the tables like this:
// Select vehicle name and manufacturer for vehicle with id of 1
$q = "SELECT v.vehicleName, m.manufacturerName, v.id AS vehicleId, m.id AS manufacturerId
FROM vehicles AS v, manufacturers AS m
WHERE v.manufacturerID = m.id
AND v.id = 1";
mysqli_query($link, $q);
I think that should answer all your questions in one way or another!

PHP & MYSQL selection

Ok folks. I have a Table categories with id, categoryname.
categories has: id=1 categoryname = batteries, id=2 categoryname = flashes, id=3 categoryname glasses.
The Second table is users. Users have id, user_eimal, my_choices.
Every user has store into my_choices the category name that wants to appear.
So for example user George with user_email xxxxx#xxx.com has store in my_choices: batteries,glasses
Now i want to bring up records from table products where categoryname is the values that user george has stored into my_choices.
Products has id, p_title, categoryname
for example i want to:
<?php
$usenmail = $_SESSION['SESS_EMAYL_NAME'];
$q1 = "SELECT * FROM categories WHERE id = '$id'";
$q2 = mysql_query($q1, $connectiondb) or die(mysql_error());
$results = mysql_fetch_assoc($q2);
$my_choices = $results['my_choices']; //That means $my_choices = batteries,glasses
//Now i want to select fom my table poducts only the categories (batteries,glasses)that user has store.
$trt = mysql_query ("select * from products where categoryname = batteries,glasses");
while($apst = mysql_fetch_assoc($trt)) {
echo '<div style="color: #000; float: left;">Productname: '.$['apst'].'</div>';
echo '<br>';
}
?>
You want to use a join table so you can have a many-to-many relationship. Your current structure is better suited to each user only having ONE choice.
What you want are three tables:
Users (userID, user_name, user_email)
Categories (categoryID, category_name)
Users_Categories (userID, categoryID)
So to use your example, your three tables would look like this (if anyone knows a better way to demonstrate SQL tables on here, please let me know):
Users
userID: 1 | user_name: George | user_email: george#example.com
Categories
categoryID: 1 | category_name: batteries
categoryID: 2 | category_name= flashes
categoryID: 3 | category_nameglasses.
Users_Categories
userID: 1 | categoryID: 1
userID: 1 | categoryID: 3
You would then use a select statement with a join clause to get George and his categories:
SELECT
user_name,
category_name
FROM
Users
LEFT JOIN Users_Categories USING (userID)
LEFT JOIN Categories USING (categoryID)
WHERE
userID = 1
This would return two rows in the result:
George, Batteries
George, Glasses
Depending on what you want to do with that data, it may be better to also select the userID.
If you want a query that will only return one row with all of the information, it gets a little trickier. You have to use the GROUP BY functionality. That would look like this:
SELECT
user_name,
GROUP_CONCAT (category_name ',')
FROM
Users
LEFT JOIN Users_Categories USING (userID)
LEFT JOIN Categories USING (categoryID)
GROUP BY
userID
WHERE
userID = 1
For your final question about products, you would follow the same logic with more joins. Your Products table wants to have a productID, product_name, and categoryID.
$trt = mysql_query ("select * from products where categoryname = 'batteries' OR categoryname = 'glasses'");
Use explode function
$array = explode(','$my_choices);
now array[0] and array[1] have the 2 values. then use
$result = mysql_query ("select * from products where categoryname = '".$array[0]."' OR categoryname = '".$array[1]."'");
In your case use select statement as,
select * from products where categoryname in ( 'batteries','glasses');
ie,
//add quotes to category names (if ids you dont neeed these 2 lines)
$cats=explode(',',$my_choices);
$strcats = "'" . join("', '", $cats) . "'";
$trt = mysql_query ("select * from products where categoryname in ($strcats));
My suggestion to use category ids instead of category names.

Categories