MySQL Retrieve repeatin results using "in" condition - php

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;

Related

How to merge and sum up certain values of items that have the same ID value

So i have 2 tables. Orders and OrderItems. Relationship is each Order can have many OrderItems (orderitem is just a product).
OrderItem Table
id INT PRIMARY KEY
name TEXT
quantity INT
pack_value INT
order_id INT FOREIGN KEY REFERENCES ORDER_ID ON ORDERS TABLE
product_id INT FOREIGN KEY REFERENCES PRODUCT_ID ON PRODUCTS TABLE
Orders Table
order_id INT PRIMARY KEY
status TEXT
user_id INT FOREIGN KEY REFERENCES USER_ID ON USERS TABLE
An order can have the same OrderItem twice or only once. For example like below, 3 items but 2 products:
OrderItem(id=1, product_id=100, name="Pizza", quantity=2, pack_value=10, order_id=7)
OrderItem(id=2, product_id=100, name="Pizza", quantity=10, pack_value=1, order_id=7)
OrderItem(id=3, product_id=555, name="Olives", quantity=5, pack_value=1, order_id=7)
So above there is 2 entries for Pizza and this is the result i get. However i want it to only show 1 entry for Pizza because its the same item. Below is what i want to see:
OrderItem(product_id=100, name="Pizza", quantity=30, pack_value=1, order_id=7)
OrderItem(product_id=555, name="Olives", quantity=5, pack_value=1, order_id=7)
So essentially, if the item only exists once, then do nothing to it. If it exists twice, then make the pack_value=1 and the quantity is the sum of the individual quantity*pack_value. So in example above quantity becomes (2*10 + 10*1 = 30).
The controller method is like below, and so here is where I want to do this:
public function showOrderDetails(Order $order){
return view('orders.show', compact('order'));
}
Also the Order and OrderItem models has the method for the relationships. For example, in the Order Model i have:
public function orderItems(){
return $this->hasMany(OrderItem::class, 'order_id');
}
Thanks, and if you need any extra info i can provide.
SELECT name,
SUM(quantity * pack_value) AS quantity,
1 AS pack_value,
order_id
FROM order_items
GROUP BY name,
order_id;
fiddle
Merge another tables to this code using it as subquery, or add them into FROM clause (adjusting its output list and grouping expression) if needed.

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.

how to insert a new record in a table that has foreign key attributes in mysql

What is wrong in this statement since customers table has only one record
INSERT INTO CART (Cartid,custid,Pid)
VALUES ('2',SELECT(custid from CUSTOMERS), SELECT (Pid from Products where Pname ='shirts'))
Make sure that the cart table id is primary key and auto_increment. Get the customer id and store in a variable. You can try something similar like this
INSERT INTO CART (Cartid,custid,Pid) VALUES ('', SELECT custid from CUSTOMERS WHERE custid = '$customer_id'),(SELECT Pid FROM Products WHERE Pname = 'shirts' LIMIT 1));
The correct syntax is:
INSERT INTO CART (Cartid, custid, Pid)
VALUES (2,
(SELECT custid FROM CUSTOMERS LIMIT 1),
(SELECT Pid FROM Products WHERE Pname = 'shirts' LIMIT 1)
);
Your parentheses are in the wrong place.
Notes:
I added the LIMIT just to enforce that one row is returned.
I removed the single quotes around '2', because ids are usually number.
You probably should not be inserting the id; it should be an auto-increment column.

updating sql values with array which have a couple times occured items

While i am coding a shopping site, I need to update product stock.
But the thing is, naturally shopping cart can have the same items a couple of times.
What is the best way for updating it?
I tried IN but the following SQL query returns 3 items.
SELECT *
FROM `products`
WHERE id
IN ( 3, 4, 4, 6 )
LIMIT 0 , 30
Here is my solution but, I don't think this is the best one.
$cart = array(1,3,4,4,5,8,22,22);
$itemlist = array_count_values($cart);
foreach($itemlist as $itemid=>$ocurrence){
$SQL = "UPDATE products SET stock = stock-".$ocurrence." WHERE id = ".$itemid;
mysql_query($SQL);
}
You can do something like this:
SELECT * FROM menu WHERE item_id = 1
UNION ALL
SELECT * FROM menu WHERE item_id = 1
UNION ALL
SELECT * FROM menu WHERE item_id = 2
Check this link:
MySQL table -> Can you return the same row multiple times, in the same query?
if possible create a seperate item_cart, table which will have (cart_id, item_id , product_id) as primary key. from here you can get do a group by on product_id to see how many no of product sold.
select product_id, count(product_id) as "No of Product Sold" from item_cart
group by product_id
your php code will update no of products in stock coloumn perfectly.
If possible you try setting triggers for updatin stock columns whenever any product is sold.

How to associate Article with multiple categories

New to PHP/MySQL and building a CMS. I need to know how to associated an Article with multiple Categories eg "My Article 1" has to be in 3 categories and "My Article 2" has to be in only 2 etc.
It's basically just the table set up to begin with. Here's what I have:
Table = articles
Fields = id, publicationDate, title, summary, content
Table = categories
Fields = id, categoryTitle
I know a little about joins and relationships etc but I want to get this right from the start.
You need a many-to-many table that will link article ids to category ids
CREATE TABLE articles_categories (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
articles_id INT,
category_id INT
) TYPE=myisam;
So for each category that you associate with an article you will need to insert a row into this table.
Perhaps something like:
$currentArticle = array('id' => 99, 'name' => 'Test Article');
$currentCategory = array('id' => 1, 'name' => 'First Category');
mysql_query(sprintf('INSERT INTO articles_categories (articles_id, category_id) VALUES (%d, %d)', $currentArticle['id'], $currentCategory['id']));
You need a third table, called articles_to_categories or whatever, with two fields:
article_id
category_id
Add an entry for each article and category association. Set the PK to be both columns.

Categories