MySQL Queries with Meta Keys and Values - mysql

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)

Related

How to subtract one table column values to the other table column values

I have two tables Stock and Sale
Stock
id Name size Qty
1 box1 10 100
2 box2 12 200
3 box3 14 500
4 box4 16 700
Sale
id Name size Qty
1 box1 10 1
2 box2 12 2
3 box3 14 5
4 box4 16 7
I want this result after Subtract Qty
Stock
id Name size Qty
1 box1 10 99
2 box2 12 198
3 box3 14 495
4 box4 16 693
Help!
You can JOIN the tables by id and name then simply subtract the Qty values. Added table alias name for better readability
SELECT ST.id, ST.Name, ST.size, (ST.Qty - SA.Qty) AS Qty
FROM Stock ST
INNER JOIN Sale SA ON SA.id = ST.id AND SA.Name = ST.Name
If you though join by Name is not needed then you can join only by id as
SELECT ST.id, ST.Name, ST.size, (ST.Qty - SA.Qty) AS Qty
FROM Stock ST
INNER JOIN Sale SA ON SA.id = ST.id
Update for SQLite
UPDATE Stock
SET Qty = ( SELECT ST.Qty - SA.Qty
FROM Stock ST
INNER JOIN Sale SA ON SA.id = ST.id )
WHERE id IN (SELECT id FROM Stock )
Got reference from this answer
Try this:
SELECT Stock.id, Stock.Name, Stock.size, (Stock.Qty - Sale.Qty) AS Qty
FROM Stock
INNER JOIN Sale ON Sale.id = Stock.id
Use the below query
Select table.id,table.name,table.size,sum(table.qty) from
(Select id,name,size,qty from stock
Union
Select id,name,size,qty*-1 from sale) as table group by table.id,table.name,table.size
If you want store the result In mysql you can (using the name for relation) update
update Stock as a
inner join Sale as b on a.name = b.name
set a.Qty = a.Qty -b.Qty
or using id for relation
update Stock as a
inner join Sale as b on a.id = b.id
set a.Qty = a.Qty -b.Qty
or if you simply want a select you can
select a.id, a.name, a.size, a.Qty -b.Qty as qty
from fromStock as a
inner join Sale as b on a.id = b.id
In sqlite the update with inner join is not allowed so you use the subselect
update Stock
set Qty = ( select Stock.Qty -Sale.Qty from Stock
Inner join Sale on Sale.name = Stock.name )
WHERE
EXISTS (
SELECT *
from Stock
Inner join Sale on Sale.name = Stock.name
)

SQL joining two tables with a LEFTJOIN

I have tables
table_order
product_name
Below is the SQL I have to query table_order which works perfectly in outputting the product_id but I need it to show it's name and not number. I need to modify mySQL with a LEFTJOIN to somehow connect with table product_name but I keep getting an error. So instead of
99 = 15, 99 = 16
I need
99 = name1, 99 = name2
SELECT table_order.order_id, table_order.product_id
FROM table_order
WHERE table_order.order_id=99
ORDER BY table_order.order_product_id
table table_order
_________________________
order_id | product_id |
_________________________
99 | 15 |
99 | 16 |
_________________________
table product_name
___________________________
product_id | product_name |
___________________________
15 | name1 |
16 | name2 |
___________________________
Use
SELECT a.product_id, b.product_name
FROM table_order AS a LEFT JOIN product_name AS b ON a.product_id = b.product_id
WHERE a.order_id = '99'
ORDER BY a.product_id
You need to join the tables, as you say, on product_id.
SELECT table_order.order_id, product_name.product_name
FROM table_order
INNER JOIN product_name on table_order.product_id = product_name.product_id
WHERE table_order.order_id=99
ORDER BY table_order.product_id
Select t1.product_id,t2.product_name from table_order as t1
inner join(
select * from product_name
) as t2
on t1.product_id = t2.product_name
where t1.product_id = //some Number
See if that works.
If you need to output all the orders regardless of whether the product id of that table_order has a connection to product_table, you need to use LEFT JOIN.
SELECT o.order_id, p.product_name
FROM table_order o
LEFT JOIN product_name p ON o.product_id = p.product_id
ORDER BY o.product_id
However if you just need to get all the rows that exists in both tables, you can use an INNER JOIN
SELECT o.order_id, p.product_name
FROM table_order o
INNER JOIN product_name p ON o.product_id = p.product_id
ORDER BY o.product_id

multiple mysql tables with multiple joins

I have 4 mysql tables as follows:
products:
----------------------------------------------------
product_id product_name price discount
----------------------------------------------------
1 product 1 10.00 1.00
2 product 2 20.00 2.00
3 product 3 25.00 1.00
----------------------------------------------------
subcategory
----------------------------------------------------
cb_category_id subcategory_name status
----------------------------------------------------
1 subcat 1 Enabled
2 subcat 2 Disabled
3 subcat 3 Enabled
------------------------------------------------------
temp_products
------------------------------------------------------
id productid catid
------------------------------------------------------
1 1 1
2 1 2
3 2 1
------------------------------------------------------
product_images
------------------------------------------------------
product_id images
------------------------------------------------------
1 image1.jpg
1 image2.jpg
2 image2-1.jpg
--------------------------------------------------------
temp_products.catid and subcategory.cb_category_id
and
temp_products.productid and products.product_id
and
products.product_id and product_images.product_id
are related..A product can have multiple images.
I wish to have a subcategory selected with all products with first image for a product from product_images and WHERE subcategory.status is "Enabled"...?? Need to limit output to only 1 cb_category_id with multiple product_id under it, like as follows:
----------------------------------------------------------------------------------
cb_category_id subcategory_name product_id product_name, price, discount, images
-----------------------------------------------------------------------------------
1 subcat 1 1 product 1 10.00 1.00 image1.jpg
1 subcat 1 2 product 2 20.00 2.00 image2- 1.jpg
My query is as follows:
SELECT p.product_id,p.product_name,p.price,p.discount,s.cb_category_id,s.subcategory_name
FROM products p,subcategory s
INNER JOIN temp_products ON p.product_id = temp_products.productid
INNER JOIN temp_products tp ON tp.catid = s.cb_category_id
WHERE tp.catid = s.cb_category_id
I am getting unknown column p.product_id in on clause ....Regarding including images i am at a dead end.
Help requested...I am unable to comprehend the joins required for the same...
you have a typo . you dont have products_id in your products table.
change this
p.products_id
to
p.product_id
EDIT: rewrite your query like that :
SELECT p.product_id,p.product_name,p.price,p.discount,s.cb_category_id,s.subcategory_name ,pi.images
FROM products p
INNER JOIN temp_products tp ON p.product_id = tp.productid
INNER JOIN product_images pi ON p.product_id = pi.product_id
INNER JOIN subcategory s ON tp.catid = s.cb_category_id
GROUP BY p.product_id
Your 'temp_products' table is basically a mapping table for 'products' and 'subcategory'. I have not tested the following code but you'll get the idea from comments(text after # character). this should solve your problem:
SELECT p.product_id,p.product_name,p.price,p.discount,s.cb_category_id,s.subcategory_name,pim.images
FROM products p
INNER JOIN temp_products tp ON p.product_id = tp.productid #remove duplicate join
INNER JOIN subcategory s ON tp.catid = s.cb_category_id
LEFT JOIN product_images pim ON pim.product_id =p.product_id #join for images
WHERE s.status = 'Enabled' AND #subcategory is enabled
s.cb_category_id = '1' #subcategory you want to be selected
GROUP BY p.product_id ORDER BY p.product_id, pim.images;

Select sold and unsold products

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

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