How to connect two MySQL tables - php

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.

Related

PHP / MYSQL Do I Need to SQL Join?

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";

Is it possbile to fetch categories sub catgeories sub sub categories in a single query for a dynamic menu?

I have two tables for categories and subcategories
Create table m_category (id int,
cat_name varchar(30),
constraint pk_catid primary key (id)
);
Create table m_item (id int,
cat_id int,
item_name varchar(30),
constraint fk_catid
foreign key (cat_id)
references m_category(id)
);
I want my menu to look likeThis.
I hope you get the picture.
The idea I have is to run a query like
$sql="SELECT * FROM m_category where id='1';
And use such queries to fetch each category and subcategory likewise.
But I want to make the menu completely dynamic and fetch the categories and subcategories in less than 3 queries.
Is it possible to do so?
You can use a join
$sql="SELECT *
FROM m_category
INNER JOIN m_item on m_category.id = m_item.fk_catid
where id='1';";
Using PDO
assuming you $dbh is your database connectio handle (if you use mysqli there are similar functionalities)
$id = 1;
$sth = $dbh->prepare("SSELECT *
FROM m_category
INNER JOIN m_item on m_category.id = m_item.fk_catid
where id= :id");
$sth->bindParam(':id', $id, PDO::PARAM_INT);

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

MySQL Retrieve repeatin results using "in" condition

Of all aspects of coding, SQL is my weakest skill, so please forgive me if I sound like I don't know what I'm talking about, because I probably don't!
Situation:
Building a shopping cart where the table named "cart" has a field named "products" of type VARCHAR 255, and the value of "products" will be a comma delimited string. Each element of the string will be a number which represents the id of a product from the "products" table.
A customer's record may contain a value in the "products" field that looks like 1,1,1,2,3. This would mean the customer has added three of item 1, one of item 2, and one of item 3.
Problem:
So, here is the sql statement I have presently, but the problem is I need a sql statement that will return repeat product data from the product table:
SELECT product_id, product_name,price
FROM products
WHERE id in ('1','1','1','2','3')
The result of that will be a set of three items from the "products" table, 1 and 2 and 3. In other words, it doesn't give me the product data for the three '1's, it only gives me a distinct value. Not 3 values from the products table, but 5 values from the products table, where the first three results are identical, because they are the same product_id=1.
I need a sql statement that will give me the redundant product information, because after all, a person can order three widgets with the product_id = 1.
cart:
id INT(15)
uid VARCHAR(32)
email VARCHAR(100)
products VARCHAR(255)
date DATETIME
checkout TINYINT(1)
products:
id INT(15)
product_id varchar(32)
product_name varchar(128)
product_associations varchar(255)
short_description varchar(255)
long_description mediumtext
price varchar(32)
image varchar(128)
My php code:
$productslist = str_replace(",","','",$row->products);
$productslist = "'" . $productslist . "'"; echo $productslist;
$sql2 = "SELECT product_id, product_name,price FROM products WHERE id in ($productslist)";
$query2 = $this->db->query($sql2);
$i = 0;
if ($query2->num_rows() > 0){
foreach ($query2->result() as $row2){
$products[$i]['product_id'] = $row2->product_id;
$products[$i]['product_name'] = $row2->product_name;
$products[$i]['price'] = $row2->price;
$i++;
}
}
...and a result of this query would be:
Product ID: #0001
Product Name: "Ducky"
Price: $1.50
Product ID: #0002
Product Name: "Horse"
Price: $1499.00
Product ID: #0003
Product Name: "T-shirt"
Price: $5.00
Update:
In the interest of best practices, I studied the "normalized" table theory, then rolled back the above scheme of a comma-delimited products field. I created a separate table called "cart_list", with the fields:
id
cart_id
product_id
...and I simply insert new records for each new "add to cart", keyed to the cart table by the cart_id field, and keyed to the product data through the product_id field.
a bit ugly but that would do the trick:
create temporary table t (id integer);
insert into t(id) values (1),(1),(2),(2),(3);
select product_id, product_name,price from t inner join products where t.id = products.id;
drop table t;

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!

Categories