Select sold and unsold products - mysql

I'm trying to select all products names and how many has been sold in current date, but I'm having a problem since not all products are sold everyday. (When the product has not been sold it must return 0)
TABLE PRODUCTS
ID NAME
1 APPLE
2 PINEAPPLE
3 COFFE
TABLE SALES
ID DATE
1 2014-01-13
2 2014-01-13
TABLE PRODUCTS_AND_SALES
SALE_ID PRODUCT_ID AMOUNT
1 3 2
1 1 1
2 3 1
What I expect to receive:
PRODUCT AMOUNT
APPLE 1
PINEAPPLE 0
COFFE 3
What I receive:
PRODUCT AMOUNT
APPLE 1
COFFE 3
My query:
select product, sum(amount) from products
join products_and_sales using (product_id)
join sales using (sale_id)
where date(dt_sale) = curdate()
group by product_id;

try this
select name as PRODUCT , ifnull(sum(AMOUNT),0) amount from products p
left join PRODUCTS_AND_SALES ps
on p.id = ps.PRODUCT_ID
group by product
DEMO HERE
EDIT:
if you wanna use specefic date then use this
select name as PRODUCT ,if(date = '2014-01-13' ,ifnull(sum(AMOUNT),0), 0 ) amount
from products p
left join PRODUCTS_AND_SALES ps on p.id = ps.PRODUCT_ID
left join SALES s on s.id = ps.SALE_ID
group by product
DEMO HERE
just replace this date 2014-01-13 by the date you want. (curdate()) or what ever

Use OUTER JOIN instead of INNER JOIN
if you show the query you use we will correct it for you.

Try this...
SELECT pr.NAME, IFNULL(SUM(prs.AMOUNT), 0)
FROM PRODUCTS pr
LEFT OUTER JOIN PRODUCTS_AND_SALES prs ON pr.id = prs.product_id
LEFT OUTER JOIN SALES sl ON sl.id = prs.sales_id AND date(s1.dt_sale) = curdate()
GROUP BY pr.NAME

Related

php - Check same column twice in mysqli query

I have 3 tables in my php based system.
Those tables are product, category, product_categories.
Product
pid | product_name | price
1 | Nike T-Shirt | 23
Category
cid | category_name
1 | Men
2 | Women
Product_categories
pcid | cid | pid
1 | 1 | 1
2 | 2 | 1
That means, 1 product may be in both multiple categories.
Now I am developing the product search section with filter.
If a user select both categories, all the products in selected categories should display.
Example : If a user select both Men & Women, Nike T-Shirt should be displayed.
The query I used:
select p.*
from products p
left join product_categories pc on pc.pid=p.pid
WHERE pc.cid ='1' AND pc.cid = '2'
But it not returning correct products.
Where is the error?
You want conditions that span over multiple rows, which suggests aggregation. You can join the tables, group by product, and use the having clause for filtering:
select p.id, p.product_name, p.price
from product p
inner join product_category pc on pc.pid = p.pid
inner join category c on c.cid = pc.cid
where c.category_name in ('Men', 'Women')
group by p.pid, p.product_name, p.price
having max(c.category_name = 'Men') = 1 and max(c.category_name = 'Women') = 1
If you can filter by category id rather than by category name, then you need one less join:
select p.id, p.product_name, p.price
from product p
inner join product_category pc on pc.pid = p.pid
where pc.cid in (1, 2)
group by p.pid, p.product_name, p.price
having max(pc.cid= 1) = 1 and max(pc.cid = 2) = 1
Here are few alternatives:
-- All products that are at lest in one of the desired categories
select * from product where product.pid = any (select product_category.pid from product_category where cid = 1 or cid = 2);
-- Products that are in both categories
select * from product where product.pid = any (
select product_category.pid from product_category where cid = 1 or cid = 2 group by pid having count(cid) = 2
);
-- Products with additional information "in how many desired categories they are"
-- You can order by it and/or filter on it
with product_category_matches as (
select pid, count(*) as category_count from product_category where cid in (1, 2) group by pid
)
select *, product_category_matches.category_count from
product inner join product_category_matches on product.pid = product_category_matches.pid
where product_category_matches.category_count > 0 -- Product must be at least in one desired category
order by product_category_matches.category_count desc

MySQL Queries with Meta Keys and Values

I have a hard time wrapping my head around coming up with a nice clean mysql query for this problem. I have two tables:
ORDER ITEMS ORDER ITEM META
----------------- ---------------------
ID Name ID Key Value
----------------- ---------------------
24 Product A 24 _qty 3
30 Product B 30 _qty 5
33 Product B 30 _weight 1000g
55 Product A 33 _qty 1
----------------- 33 _weight 500g
55 _qty 2
---------------------
I ran this query:
SELECT
oi.ID,
oi.Name,
oim1.Value as Qty,
oim2.Value as Weight
FROM
`order_items` as oi
INNER JOIN `order_item_meta` as oim1 ON oim1.ID = oi.ID
INNER JOIN `order_item_meta` as oim2 ON oim2.ID = oi.ID
WHERE
oim1.Key = '_qty' AND
oim2.Key = 'weight'
But it only gives me
-------------------------------
ID Name Qty Weight
-------------------------------
30 Product B 5 1000g
33 Product B 1 500g
-------------------------------
I need to include products that do not have _weight defined as a key so it will give me the following results:
-------------------------------
ID Name Qty Weight
-------------------------------
24 Product A 3
30 Product B 5 1000g
33 Product B 1 500g
55 Product A 2
-------------------------------
Try using an outer join:
select oi.id, oi.name, oim1.value as qty, oim2.value as weight
from order_items as oi
join order_item_meta as oim1
on oim1.id = oi.id
left join order_item_meta as oim2
on oim2.id = oi.id
and oim2.key = '_weight'
where oim1.key = '_qty'
Fiddle Test:
http://sqlfiddle.com/#!2/dd3ad6/2/0
If there is ever a situation where an order doesn't have a quantity you would also have to use an outer join for the quantity, like this:
select oi.id, oi.name, oim1.value as qty, oim2.value as weight
from order_items as oi
left join order_item_meta as oim1
on oim1.id = oi.id
and oim1.key = '_qty'
left join order_item_meta as oim2
on oim2.id = oi.id
and oim2.key = '_weight'
However if an order ALWAYS has an associated quantity (just not necessarily an associated weight) you should use the first query instead, an inner join for the quantity, and an outer join for the weight. (it all depends on your situation)

Join two table. One column using SUM

I need a little help with a MySQL query.
I have two tables one table is a list of product and one table is a list of warehouses quantity
product:
product_id product_name
1 name1
2 name2
3 name3
warehouse_product
id warehouse_id product_id product_quantity
1 1 1 15
2 2 1 30
3 1 2 100
4 2 2 30
5 1 3 20
6 2 3 40
The results Im looking to get from the above data would be
product_id product_name product_quantity
1 name1 45
2 name2 130
3 name3 60
I've tried many query but it's not working. My query is:
SELECT
product_id as product_id, SUM(quantity) as quantity
FROM
(SELECT
p.product_id as product_id, wp.product_quantity as quantity
FROM
product as p
LEFT JOIN warehouse_product as wp ON p.product_id = wp.product_id
WHERE
product_active = 1)
Try this:
SELECT p.product_id, p.product_name, SUM(wp.quantity) as quantity
FROM product as p
LEFT JOIN warehouse_product as wp
ON p.product_id = wp.product_id
AND product_active = 1
GROUP BY p.product_id, p.product_name
After JOINing the two tables you need to use GROUP BY so that SUM of quantity can be calculated for each product.
select p.product_id,p.product_name,sum(product_quantity) as 'product_quantity'
from product p inner join warehouse_product whp on
whp.product_id=p.product_id group by whp.product_id
select p.product_id, p.product_name,sum(w.product_quantity)
from
product p
inner join
warehouse_product w
on
p.product_id = w.product_id
group by w.product_id
order by p.product_name;
SELECT P.productid,
P.ProductName,
Sum(W.product_quantity) As quantity
FROM Product AS P
LEFT JOIN warehouse_product AS W
ON P.productid = W.productid
GROUP BY P.ProductId , P.ProductName
SQLFiddle

MySQL join table return only one match

I'm struggling the the JOIN in a MySQL query. Somehow I can't find out why my result is not what I want.
I have two tables, a table orders and a table products. The table product holds the order.id of the order. So a order can have more than one products, so for example the table products holds two records for a order.
The result I need is all orders where a product holds a VAT of 21.
Table example.
orders
id | customer
---------------
1 | John Doe
2 | Hello World
order_products
id | order_id | product | vat
1 | 1 | Porsche 911 GT4 | 21
2 | 1 | Audi R8 LMS | 21
3 | 1 | Ferrari Enzo | 19
3 | 2 | Bugatti Veyron | 19
No I want all orders where the products have a VAT of 21. So I will do a LEFT JOIN on the table order_products:
SELECT orders.id, orders.customer, order_products.product FROM orders LEFT JOIN order_products ON orders.id = order_products.order_id WHERE order_products.vat = '21'
This returns the following:
1 John Doe Porsche
1 John Doe Audi R8 LMS
But I only need one result because the orders.id is important for me, not all products in the order. I only join on the order_products to get the orders with only VAT 21. At the moment I ran out of options on how to fix this. Even after reading several topics about joins on this site and other sites.
First, you aren't going to return any orders that don't have products, so there is no need for a left join...an inner join is fine.
If the orders_product is not important to you, you can use a subquery and not select any columns from the orders_product. With your current query, you're selecting a column though.
Something like...
SELECT id, customer
FROM orders
WHERE order_id IN (SELECT order_id FROM order_products
WHERE order_products.vat = '21');
If you prefer not to use a correlated subquery, you can use a group by or distinct
SELECT orders.id, orders.customer
FROM orders
INNER JOIN order_products ON orders.id = order_products.order_id
WHERE order_products.vat = '21'
GROUP BY orders.id, orders.customer;
or...
SELECT DISTINCT orders.id, orders.customer
FROM orders
INNER JOIN order_products ON orders.id = order_products.order_id
WHERE order_products.vat = '21';
If you only care about the orders then you can group by the order id:
SELECT orders.id, orders.customer, order_products.product
FROM orders
LEFT JOIN order_products ON orders.id = order_products.order_id
WHERE order_products.vat = '21'
GROUP BY orders.id;
However note that order_products.product will only be one of the products. If you wish to display all of the products but in the one column you can user GROUP_CONCAT:
SELECT orders.id, orders.customer, GROUP_CONCAT(order_products.product)
FROM orders
LEFT JOIN order_products ON orders.id = order_products.order_id
WHERE order_products.vat = '21'
GROUP BY orders.id;
This will return:
1 John Doe Porsche, Audi R8 LMS
SELECT DISTINCT o.id
, o.customer
FROM orders o
JOIN order_products op
ON op.order_id = o.id
WHERE op.vat = 21;

mysql count, distinct, join? Confusion

i have 2 tables:
tblItems
ID | orderID | productID
1 1 2
2 1 2
3 2 1
4 3 2
tblProducts
productID | productName
1 ABC
2 DEF
im attempting to find the most popular Product based on whats in "tblItems", and display the product Name and the number of times it appears in the tblItems table.
i can get mysql to count up the total like:
$sql="SELECT COUNT(productID) AS CountProductID FROM tblItems";
but i can't figure out how to join the products table on..if i try LEFT JOIN the query goes horribly wrong
hopefully thats not too confusing..thankss
Are you simply trying to find the count of orders by product like so:
Select P.ProductName, Count(*)
From tblItems As I
Join tblProducts As P
On P.ProductId = I.ProductId
Group By P.ProductName
I think you may be looking for something like:
SELECT tblProducts.productName, COUNT(tblItems.ID)
FROM tblProducts
LEFT JOIN tblItems USING(productID)
GROUP BY tblProducts.productID
SELECT count(i.productID) AS cnt, p.productName FROM tblItems AS i
LEFT JOIN tblProducts AS p ON p.productID = i.productID
GROUP BY i.productID
ORDER BY cnt desc