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

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.

Related

Select only those records that have multiple value in same table

I have only those rows that have multiple rows in the same table. For example see below image.
In the above picture you can see 2 highlighted columns one is for useid(u_id) and second is for product id (product_id).
So you can see user id of 7 has multiple product like (78,40,44,45,53) and user id 9 has multiple products like (79,75,79) same like user id 40 has multiple products.
so want out put like if particular user have multiple products then it will display 'multiple product' in product name column instead of display all product name.
above picture display all product but i need to display 'multiple product' message instead of all products if particular user have multiple products
I have used following query but not getting result that i want .
SELECT *
FROM orderlist
WHERE product_id IN (
SELECT product_id
FROM orderlist
GROUP BY product_id
HAVING COUNT(*) > 1
)
You could do the JOINS after aggregation
SELECT *,
CASE WHEN c.Counts > 1 THEN 'Multi' ELSE o.ProductName END ProductName
FROM
(
SELECT product_id, COUNT(*) Counts
FROM orderlist
GROUP BY product_id
)c INNER JOIN orderlist o ON o.product_id = c.product_id

mysql query to get count of products along with quantity

SELECT product,quantity,count(product) AS count
FROM order_table WHERE order_id in
(select order_id from progress)
group by product
using this query i get product name and count of products. but, i also have quantity column in my table. so, when product gets 2 quantity how to add that quantity along with product count with this above query.
in the above image there are 3 burger products and 2 quantity for one burger product, here i need to show like product : burger and total quantity : 4 later in next line product : pizza and total quantity : 3
SELECT product,sum(quantity)as 'quantity',count(product) AS count
FROM order_table WHERE order_id in
(select order_id from progress)
group by product
Just a use aggrigate function sum on quantity.
Need some sample data. Input data and expected output.
Till then try it out this query --
SELECT Product
,SUM(Quantity) AS Total_Quantity
,COUNT(Product) AS Product_Count
FROM order_table
WHERE order_id IN (
SELECT DISTINCT order_id
FROM Progress
)
GROUP BY Product
Without sample data it is difficult to guess, but looking at your question, looks like you need something like this
SELECT product
,sum(quantity) as total_quantity
,count(*) AS count
FROM order_table
WHERE order_id in
(select order_id from progress)
group by product

Need SQL query with good performance to select data that does NOT match criteria

I have a database with
a company table
a country table
a company_country n:n table which defines which company is available in which country
a product table (each product belongs to one specific categoryId)
and a company_product_country n:n:n table that defines which company offers which product in which country.
The latter has the three primary key columns companyId, productId, countryId and the additional columns val and limitedAvailability. val is an ENUM with the values yes|no|n/a, and limitedAvailability is an ENUM with the values 0|1.
Products within categories 1 or 2 are available in all countries and therefore get countryId = 0. But at the same time, only these very products may have a limitedAvailability = 1.
An SQLFiddle with a test database can be found here: http://www.sqlfiddle.com/#!9/a065a/1/0
It contains five countries, products and companies.
Background information on what I need to select from the database:
A PHP script generates a search form where an arbitrary list of countries and products can be selected. The products are separated by categories (I did not add the category table in the sample database, because it is not needed in this case). For the first category, I can select whether to exclude products with limited availability.
Generating the desired result works fine:
It displays all companies that are available in the selected countries and have at least one of the selected products available. The result offers a column that defines how many of the selected products are available by company.
If the user defines that one or more categories should not contain products with limited availability, then the products within the corresponding categories will not count as a match if the company offers them with limited availability only.
I am pleased with the performance of this query. My original database has got around 15 countries, 100 companies and 150 products. Selecting everything in the search form occupies the MySQL server for around two seconds which is acceptable for me.
The problem:
After generating the result list of companies which matches as many product search criteria as possible, I use PHP to iterate through those companies and run another SQL query that should give me the list of products that the company does not offer corresponding to the search criteria. The following is an example query for companyId 1 to find out which products are not available when
the desired products have the productIds 2, 4 and 5
the product's country availability should be at least one of the countryIds 1, 2 or 3
the product should not have a limitedAvailability when it is from categoryId = 2:
SELECT DISTINCT p.name
FROM `product` p
LEFT JOIN `company_product_country` cpc ON `p`.`productId` = `cpc`.`productId` AND `cpc`.`companyId` = 1
WHERE NOT EXISTS(
SELECT *
FROM company_product_country cpcTmp
WHERE `cpcTmp`.`companyId` = 1
AND cpcTmp.val = 'yes'
AND (
cpcTmp.limitedAvailability = 0
OR p.categoryId NOT IN(2)
)
AND cpcTmp.productId = p.productId
)
AND p.`productId` IN (2,4,5)
AND countryId IN(0,1,2,3);
The database along with this query can be found on the SQLFiddle linked above.
The query generates the correct result, but its performance dramatically decreases with the number of products. My local SQL server needs about 4 seconds per company when searching for 150 products in 15 countries. This is inaccpetable when iterating through 100 companies. Is there any way to improve this query, like avoiding the IN(...) function containing up to 150 products? Or should I maybe split the query into two like so:
First fetch the unmatched products that do not have country Id 0 and are IN the desired countryIds
Then fetch the unmatched products in countryId = 0 and if applicable filter limitedAvailability = 0
?
Your help is gladly appreciated!
I would suggest writing the query like this:
SELECT p.name
FROM product p
WHERE EXISTS (select 1
from company_product_country cpc
where p.productid = cpc.productid and
cpc.companyid = 1 and
cpc.countryid in (1, 2, 3)
) and
NOT EXISTS (select 1
from company_product_country cpcTmp
where cpcTmp.productId = p.productId and
cpcTmp.companyId = 1 and
cpcTmp.val = 'yes' and
cpcTmp.limitedAvailability = 0
) AND
NOT EXISTS (select 1
from company_product_country cpcTmp
where cpcTmp.productId = p.productId and
cpcTmp.companyId = 1 and
cpcTmp.val = 'yes' and
p.categoryId NOT IN (2)
)
p.`productId` IN (2, 4, 5) ;
Then, you want the following indexes:
product(productid, categoryid, name)
company_product_country(productid, companyid, countryid)
company_product_country(productid, companyid, val, limitedavailability)
company_product_country(productid, companyid, val, category)
Note: these indexes completely "cover" the query, meaning that all columns in the query come from the indexes. For most purposes, is probably sufficient to have a single index on company_product_country. Any of the three would do.
Take the query that identifies the products that match the user selection. Subquery it and outer join it to the products table. Exclude the matches.
SQL Fiddle
SELECT p.name
FROM
product p LEFT JOIN
(
SELECT productId
FROM company_product_country cpcTmp
WHERE companyId = 1 AND
countryId IN (0,1,2,3) AND
(
productId IN (4, 5) OR
(productId = 2 AND limitedAvailability = 0)
)
) t
ON p.productId = t.productId
WHERE
t.productId IS NULL AND
p.productId IN (2,4,5)

php shopping cart -group by selection and get the total

My question is a little bit long...
This is the is the first picture for my question:
---Here it is the query how I make the selection:
$costumer_name=$_SESSION['p_user'];
$date=date("y-m-d");
$query_8="select * from orders
where costumer_name='$costumer_name' && date='$date'
order by product_id desc";
$result_8=mysql_query($query_8);
---As you see, the selection table needs a group by query and here is that query and the result:
$costumer_name=$_SESSION['p_user'];
$date=date("y-m-d");
$query_8="select * from orders
where costumer_name='$costumer_name' && date='$date'
group by product_id desc";
$result_8=mysql_query($query_8);
---Here it is how I get the SUM:
$query_9="select SUM(totali) as totali from orders where costumer_name='$costumer_name' && date='$date'";
$result_9=mysql_query($query_9);
$row_9=mysql_fetch_array($result_9);
$totali=$row_9['totali'];
---And finaly the problem:
1.How to count the number of orders with the same product_id(sasia)?
2.Get the first total of -cmimi and -sasia?
3.Get the final total?
Thank you
first of all i think there is better solution then every time when somebody click add to cart button to always insert new row in the database. If product is already there you should update quantity by +1, that way you will have only one row of one products instead of 3. I don't know exactly how your database look but here is an idea how you could do that:
CREATE PROCEDURE add_to_cart(IN in_cart_id INT, IN in_product_id...)
BEGIN
DECLARE quant INT;
SELECT quantity
FROM cart
WHERE cart_id = in_cart_id
AND product_id = in_product_id
INTO quant;
IF quant IS NULL then
INSERT INTO cart....
ELSE
UPDATE cart
SET quantity = quantity + 1
WHERE cart_id = in_cart_id
AND product_id = in_product_id;
END IF;
END$$
I think that is much better solution but if you want to do that the way you started then here is a way to do that:
SELECT productId, name, price, COUNT(quantity) as quantity, (price * COUNT(quantity)) as total
FROM where-ever-you store data
WHERE expression
GROUP BY productId;
that is answer on two your question, for the third total sum you need to write separate SELECT statement
SELECT SUM(price * quantity) as total_sum
FROM where-ever-you-store-data
WHERE expression if needed...

output results from 2 mySQLtables

I have 2 tables in my mySQL database csm and csmproducts.
Table csm stores the customer info and table csmproducts stores the products they ordered.
"Order_ID" is the common variable in both tables.
I have written a query which pulls data from both tables.
My query looks like this:
$query = "SELECT c.*, p.Product_SKU from csm c, csmproducts p where c.Order_ID = p.Order_ID and c.Order_Status='Awaiting Fulfillment' group by Order_ID order by Order_ID DESC LIMIT $startrow, 50";
$numresults=mysql_query($query);
$numrows=mysql_num_rows($numresults);
}
The trouble I am having is that if one order (hence one Order_ID) has multiple products in it , only the first product is showing.
What do I need to do so that where {$row['Product_SKU']} gives me only the first product for a particular Order_ID, that I am able to pull all the Product_SKUs for that particular Order_ID?
For example Order_ID 5558 has 3 products associated with it (DSC-3433, ASD-6454, UFY-7383)
Currently the output looks like this (showing just the first item the customer orderd)
Order ID: 5558
Product SKU: DSC3433
I would like to see it like this:
Order ID: 5558
Product SKU: DSC-3433, ASD-6454, UFY-7383
That is: all 3 products associated with that Order_ID to be shown.
Thanks in advance for the assistance.
USE GROUP_CONCAT
with exlplanation

Categories