Need help with a mysql query - mysql

I have a mysql query that is trying to combine the following tables:
TABLE: orders_products
products_id
orders_id
products_quantity
products_price
TABLE: products
products_id
products_model
I want a query that returns the total number of sales, the total sales value for each product_id, and the product_model for each product in the orders_products table. This is the best I've come up with so far and it just adds everything into the same bucket:
SELECT
SUM( op.products_quantity ) AS num_sold
,SUM( op.final_price * op.products_quantity )
,p.products_model
FROM orders_products AS op
JOIN products AS p
WHERE p.products_id = op.products_id

Add a group by p.products_id after your where and you will be good

SELECT p.products_id, p.products_model,
SUM( op.products_quantity ) AS num_sold
,SUM( op.final_price * op.products_quantity ) AS sales
FROM orders_products AS op
JOIN products AS p
WHERE p.products_id = op.products_id
GROUP BY p.products_id, p.products_model

You need to use GROUP BY. Check this link: http://www.w3schools.com/sql/sql_groupby.asp

Related

select sum qty from 2 tables

In MySQL I have 4 tables:
- product(id)
- order(id)
- order_detail_1(id, product_id, order_id, qty)
- order_detail_2(id, product_id, order_id, qty)
I want to get the sum of the quantity of products sold from the 2 tables (order_detail_1, order_detail_2) grouping them by product
produt can existe in order_detail_1 and not in order_detail_2 and vice versa
i tested this query and it worked but I want a simpler query without the union and the subquery.
select tmp.product_id ,sum(tmp.qty) from
(
(
select order_detail_1.product_id ,sum(order_detail_1.qty)
from order_detail_1
inner join order on order_detail_1.id_order = order.id
where order_detail_1.product_id is not null
group by order_detail_1.product_id
)
union all
(
select order_detail_2.product_id ,sum(order_detail_2.qty)
from order_detail_2
inner join order on order_detail_2.id_order = order.id
where order_detail_2.product_id is not null
group by order_detail_2.product_id
)
) tmp
group by tmp.product_id
It looks like you're not using order table other then checking if it exists, so you can use EXISTS()
SELECT p.product_id,sum(p.qty) as qty
FROM (SELECT product_id,qty,id_order FROM order_detail_1
WHERE product_id IS NOT NULL
UNION ALL
SELECT product_id,qty,id_order FROM order_detail_2
WHERE product_id IS NOT NULL) p
WHERE EXISTS(SELECT 1 FROM order o
WHERE o.id = p.id_order)
GROUP BY p.product_id
If a product is in only one table, you can use left join:
select p.id, (coalesce(sum(od1.qty), 0) + coalesce(sum(od2.qty, 0))) as qty
from product p left join
order_detail_1 od1
on od1.product_id = p.id left join
order_detail_2 od2
on od2.product_id = p.id
group by p.id;
This formulation depends on the fact that the two tables are exclusion -- a product is in only one table.
EDIT:
If products can exist in both tables, then you need to aggregate them first:
select p.id, (coalesce(od1.qty, 0) + coalesce(od2.qty, 0)) as qty
from product p left join
(select product_id, sum(qty) as qty
from order_detail_1 od1
group by product_id
) od1
on od1.product_id = p.id left join
(select product_id, sum(qty) as qty
from order_detail_2 od2
group by product_id
) od2
on od2.product_id = p.id;

Replacing id with name form another table in existing query

here's my query for getting the remaining stocks of each Product_Id. However, I'm not sure how to go about adding Product_Name from Product table. I just want to replace the i.Product_Id with p.Product_Name with p being the alias of Product. I know that the Product p should be inserted in the FROM but not sure how to connect it with the given query.
By the way, Product.Id = Inventory.Product_Id
SELECT
i.Product_Id,
i.Stocks,
s.Sales,
i.Stocks - s.Sales AS Remaining
FROM (SELECT product_id, COALESCE(SUM(quantity),0) AS Stocks FROM inventory GROUP BY product_id) i
LEFT JOIN (SELECT product_id, COALESCE(SUM(quantity),0) AS Sales FROM sales_detail GROUP BY product_id ) s
USING(product_id);
Thanks in advance guys!
UPDATE!!
The query below is my updated one, can someone check if I linked the product correctly with the existing JOIN USING, thanks!
SELECT
i.Product_Id,
p.Product_Name,
i.Stocks,
s.Sales,
i.Stocks - s.Sales AS Remaining
FROM (SELECT product_id, COALESCE(SUM(quantity),0) AS Stocks FROM inventory GROUP BY product_id) i
LEFT JOIN (SELECT product_id, COALESCE(SUM(quantity),0) AS Sales FROM sales_detail GROUP BY product_id ) s
USING(product_id)
JOIN Product p
ON i.Product_Id=p.Id;
You just need to JOIN with the Products table.
SELECT
p.Product_Name,
i.Stocks,
s.Sales,
i.Stocks - s.Sales AS Remaining
FROM (SELECT product_id, COALESCE(SUM(quantity),0) AS Stocks FROM inventory GROUP BY product_id) i
JOIN Products AS p USING (product_id)
LEFT JOIN (SELECT product_id, COALESCE(SUM(quantity),0) AS Sales FROM sales_detail GROUP BY product_id ) s
USING(product_id)

Select from 3 tables with two order by before two group by

I try to get a list of products with each newest and lowest offer price
Table product:
id | name
Table offer:
id | product_id | price | created | dealer_id
Table invalids:
id | offer_id | status
I have tried:
SELECT * FROM product INNER JOIN
(
SELECT offer.product_id , offer.price
FROM offer
LEFT JOIN invalids
ON offer.id = invalids.offer_id
WHERE invalids.id IS NULL
GROUP BY offer.dealer_id
ORDER BY offer.created DESC
) o
ON o.product_id = product.id
ORDER BY product.name
I have tried an sqlfiddle http://sqlfiddle.com/#!9/32658/3 with this offer values:
(`id`, `price`, `dealer_id`, `product_id`, `created`)
(1,12.60,1,1,'2015-05-17 08:44:45'),
(2,13.00,1,1,'2015-08-17 08:44:45'),
(3,20.00,1,1,'2015-08-17 08:45:30'),
(4,10.00,1,1,'2015-08-17 08:45:46'),
(5,4.00,2,1,'2015-05-17 08:44:11'),
(6,11.00,2,1,'2015-08-17 08:44:46'),
(7,5.00,2,1,'2015-08-17 08:45:31'),
(9,110.00,2,2,'2015-08-17 08:46:58'),
(10,11.00,2,2,'2015-08-17 08:47:12');
Expected value for product ID 1 is offer ID 7 with price 5.
These steps I think I must realize:
Order offers by created and group by dealer_id to get newest entries
Take result from step 1 and order it by price to get smallest price.
Make this for all products
Maybe I must use a second SELECT FROM offer with GROUP BY and ORDER BY but how do I get I the product_id from the first (outer) select?
Well I would start by getting the latest date for each product offer like this:
SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id;
Once you have that, you can join it to the original table to get that offer:
SELECT o.*
FROM offer o
JOIN(
SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id) tmp ON tmp.product_id = o.product_id AND tmp.latestOffer = o.created;
Here is an SQL Fiddle example.
This query should help you:
SELECT *
FROM product
JOIN (
SELECT product_id, min(price) as minPrice, max(created) as newestOffer
FROM offer
WHERE id NOT IN (SELECT offer_id FROM invalids)
GROUP BY 1
) as b
ON product.id = b.product_id
A shot in the dark based on what I understand you to be after...
lots of nested subqueries.. keep thinking there's got to be a better way...
SELECT OO.ID, OO.Price, OO.Dealer_Id, OO.Product_ID, OO.created, P.name
FROM Offer OO
INNER JOIN (
SELECT Min(Price) as MinP
FROM offer O
INNER JOIN (
SELECT max(OI.created) as LatestOffer, OI.Dealer_ID, OI.Product_ID
FROM Offer OI
LEFT JOIN invalids I
on OI.Id = I.offer_Id
WHERE I.ID is null
GROUP BY OI.Dealer_Id, OI.Product_Id
) B
on O.Dealer_Id = B.Dealer_Id
and O.Product_Id = B.Product_Id
and O.Created = B.LatestOffer
) Z
on OO.Price = Z.MinP
INNER JOIN product P
on P.ID = OO.Product_ID
SQL FIDDLE

MySQL count group by

I have 3 tables, orders(orders_id, date, ...), products (product_id, product_name, product_price) and order_products (product_id, orders_id, product_id, products_quantity) and I need to group the products so that they are displayed by product and total quantity per product to make it easier for the eshop manager to know how many items per product have been ordered.
I'm having a little bot of trouble thinking of the correct sql syntax, I keep bumping into group by issues and i'd like some help.
This is what I've done so far
select *, op.products_quantity as pquant, count(*) as `count`
from orders o
left join orders_products op on o.orders_id = op.orders_id
left join products p on op.products_id = p.products_id
group by op.orders_products_id
order by op.products_id desc;
Looking at what you have, you're counting orders, not summing the quantity of the orders..
So
if you had
orders
monday 5 potatoes
tuesday 2 carrots
wednesday 3 potatoes
You wanted
potatoes 8
carrots 2
in which case you'd want to do
select sum(quantity),item from orders group by item
I didnt quite see what the differende between orders_products and orders was.
Maybe a bit of sample data would help?
Select p.Product_name,sum(prodcuts_quantity) as OrderedQuantity from
Order_products op join
Products p on p.Product_id = op.product_id
group by p.Product_name
If you need Total quantity and total orders per product than you can do that in following way
SELECT p.*,op.total_order,op.total_quantity FROM PRODUCT LEFT JOIN (SELECT COUNT(*) AS total_order, SUM(quantity) AS total_quantity FROM orders_products GROUP BY product_id) AS op ON p.id = op.product_id
This should work, use SUM, not COUNT:
SELECT
*,
SUM(op.products_quantity)
FROM
orders AS o
LEFT JOIN orders_products AS op ON o.orders_id = op.orders_id
LEFT JOIN products AS p ON op.products_id = p.products_id
GROUP BY p.products_id
ORDER BY p.products_id DESC

Need help with a mysql query

I've developed a mysql query that tells me how many times each product was purchased over a specified timeframe. I'm trying to figure out how to join this with my pageview tracking table so I can calculate the conversion rate for each product. Here is the original query:
SELECT SUM( op.products_quantity ) AS num_sold, SUM( op.final_price * op.products_quantity ) AS total_sales, p.products_model, pd.products_name, p.products_id
FROM orders_products AS op
JOIN products AS p
JOIN products_description AS pd
JOIN orders as o
WHERE p.products_id = op.products_id
AND p.products_id = pd.products_id
AND op.orders_id = o.orders_id
AND o.date_purchased BETWEEN '2011-01-15' AND '2011-04-15"'
GROUP BY p.products_id
ORDER BY total_sales DESC
I have another query that gives me the page views per product:
SELECT pv.products_id, count( pv.timestamp )
FROM products_visits AS pv
WHERE pv.timestamp
BETWEEN '2011-01-15'
AND '2011-04-17'
GROUP BY products_id
The caveat is that the views data has just started being collected, so we want return results even if a given product_id is not in the views table, but is in the purchases table.
How do I combine those queries into a single query?
You need a LEFT OUTER JOIN against a subquery. I think this will do the job:
SELECT
SUM( op.products_quantity ) AS num_sold,
SUM( op.final_price * op.products_quantity ) AS total_sales,
p.products_model, pd.products_name,
p.products_id,
visits.visits
FROM orders_products AS op
JOIN products AS p
JOIN products_description AS pd
JOIN orders as o
LEFT OUTER JOIN (
SELECT pv.products_id, count( pv.timestamp ) AS visits
FROM products_visits AS pv
WHERE pv.timestamp BETWEEN '2011-01-15' AND '2011-04-17'
GROUP BY products_id
) visits ON p.products_id = visits.products_id
WHERE p.products_id = op.products_id
AND p.products_id = pd.products_id
AND op.orders_id = o.orders_id
AND o.date_purchased BETWEEN '2011-01-15' AND '2011-04-15"'
GROUP BY p.products_id
ORDER BY total_sales DESC
You will need to use a LEFT JOIN: "first" you get all products and their sales data, and then you join the views data, if it exists.
try this:
SELECT p.products_id,
count( pv.timestamp ) AS views,
p.products_model AS model,
SUM( op.products_quantity ) AS num_sold,
SUM( op.final_price * op.products_quantity ) AS total_sales,
pd.products_name
FROM products AS p
LEFT JOIN products_visits AS pv
ON pv.products_id = p.products_id
AND pv.timestamp BETWEEN '2011-01-15' AND '2011-04-17'
JOIN orders_products AS op
ON p.products_id = op.products_id
JOIN products_description AS pd
ON p.products_id = pd.products_id
JOIN orders as o
ON op.orders_id = o.orders_id
AND o.date_purchased BETWEEN '2011-01-15' AND '2011-04-17'
GROUP BY p.products_id
ORDER BY total_sales DESC