MySQL Query to fetch data from multiple tables - mysql

I have following tables
1) Products (productid, name, description, price)
2) Sales (salesid, productid, buyername, buyeremail, status)
3) ProductViews (viewid, productid)
Now, I need a query that can output as
ProductID ProductName Price TotalViews TotalSales
Help appreciated, thanks.

SELECT p.productid, p.name, p.price, COUNT(pv.viewid) AS totalviews, COUNT(s.salesid) AS totalsales
FROM Products p
LEFT JOIN Sales s ON s.productid = p.productid
LEFT JOIN ProductViews pv ON pv.productid = p.productid
GROUP BY p.productid, p.name, p.price
Extended group by for completeness sake but it could just be p.productid.

You can use subqueries to get the count of views and sales:
SELECT
a.productid,
a.name,
a.price,
(SELECT COUNT(b.viewid)
FROM ProductViews b
WHERE b.productid = a.productid) as TotalViews,
(SELECT COUNT(c.salesid)
FROM Sales c
WHERE c.productid = a.productid) as TotalSales
FROM
Products a

Select p.ProductID, p.ProductName, p.Price, s.c as TotalSales, v.c as TotalViews
FROM Products p
INNER JOIN (select productid, count(*) as c from Sales group by productid) s
ON s.productId = p.productid
INNER JOIN (select productid, count(*) as c from ProductViews group by productid) v
ON p.productId = v.productid
If you have a product that doesn't have a sale or a view you will need to left join instead

SELECT a.productid, a.name, a.price, (
SELECT COUNT( b.viewid )
FROM ProductViews b
WHERE b.productid = a.productid
) AS TotalViews, (
SELECT COUNT( c.salesid )
FROM Sales c
WHERE c.productid = a.productid
) AS TotalSales
FROM products a

Related

How to do GROUP BY and COUNT(*) in JOIN MySQL

I have tables named company, product, purchase_order, skid, process_record and I want MySQL query result as below.
I tried
SELECT s.id as skidId, s.skidBarcode, po.poNumber, s.companyId, c.companyName, p.productId , p.productName, totalProcessed
FROM skid s
INNER JOIN company c ON s.companyId = c.id
INNER JOIN purchase_order po on s.purchaseOrderId = po.id
INNER JOIN product prdct on p.productId = prdct.id
LEFT JOIN (SELECT skidID, productId , COUNT(*) as processedQuantity FROM process_record GROUP BY productId ) p ON p.skidID= s.id
WHERE s.status = 'closed' ORDER By s.companyId,s.id
However, this query result gives processedQuantity count NULL and random wrong count on some rows.
How can I get the desired MySQL query output as shown in screenshot?
I added GROUP BY skidID, productId instead of GROUP BY productId and it resolved the issue.
SELECT s.id as skidId, s.skidBarcode, po.poNumber, s.companyId, c.companyName, p.productId , p.productName, totalProcessed
FROM skid s
LEFT JOIN (SELECT skidID, productId , COUNT(*) as processedQuantity FROM process_record GROUP BY skidID, productId ) p ON p.skidID= s.id
INNER JOIN company c ON s.companyId = c.id
INNER JOIN purchase_order po on s.purchaseOrderId = po.id
INNER JOIN product prdct on p.productId = prdct.id
WHERE s.status = 'closed' ORDER By s.companyId,s.id

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;

MySQL - Using subqueries on join and from

I am trying to return the CustomerID, CompanyName, OrderID, and subtotals for each customer for all order the subtotal amounts that are higher than the customer’s average subtotal amount. These are the tables I am using and the query below. I am unsure if the values I return are correct and was hoping someone could help me understand if they are or not based on my query. Thanks in advance.
Orders
Columns
OrderID
CustomerID
EmployeeID
OrderDate
RequiredDate
OrderDetails
Columns
OrderID
ProductID
UnitPrice
Quantity
Products
Columns
ProductID
ProductName
QuantityPerUnit
UnitPrice
Customers
Columns
CustomerID
CompanyName
ContactName
Country
SELECT A.CustomerID, A.CompanyName, A.Subtotal, A.OrderID, AVGSubtotal
FROM (
SELECT
C.CustomerID,
C.CompanyName,
(D.UnitPrice * P.QuantityPerUnit) AS Subtotal,
D.OrderID
FROM Customers C
JOIN Orders O ON C.CustomerID = O.CustomerID
JOIN OrderDetails D ON D.OrderID = O.OrderID
JOIN Products P ON P.ProductID = D.ProductID
GROUP BY
D.OrderID, C.CustomerID
) A
JOIN (
SELECT
S.CustomerID, S.CompanyName, AVG(S.Subtotal) as AVGSubtotal
FROM (
SELECT
C.CustomerID,
C.CompanyName,
(D.UnitPrice * P.QuantityPerUnit) AS Subtotal
FROM Customers C
JOIN Orders O ON C.CustomerID = O.CustomerID
JOIN OrderDetails D ON D.OrderID = O.OrderID
JOIN Products P ON P.ProductID = D.ProductID
GROUP BY
D.OrderID, C.CustomerID
) S
GROUP BY
S.CustomerID
) B ON A.CustomerID = B.CustomerID
WHERE
A.CustomerID = B.CustomerID AND
A.Subtotal > B.AVGSubtotal
ORDER BY
A.CustomerID, A.CompanyName
;
select
c2.customerID,
c2.CompanyName,
c2.AVGSubtotal
o2.OrderID,
o2.UnitPrice * o2.Quantity as subtotal
from (
select
c.CustomerID,
c.CompanyName,
sum(o.UnitPrice * o.Quantity)/count(*) as AVGSubtotal
from
Customers c
inner join Orders o on (o.CustomerID = c.CustomerID)
inner join OrderDetails od on (od.OrderID = c.OrderID)
group by
o.CustomerID
) as c2
inner join Orders o2 on (o2.CustomerID = c2.CustomerID)
where o2.UnitPrice * o2.Quantity > c2.AVGSubtotal

Select top sales products

I have three tables like this
orders(id, status, ...)
products(id, created_at, ...)
product_order(order_id, product_id, quantity)
I want to select the most sold products first then continue with latest products taking the quantity in consideration, Here's my try
SELECT products.* FROM products
LEFT JOIN product_order ON product_order.product_id = products.id
LEFT JOIN orders ON orders.id = product_order.order_id
WHERE orders.status != 'REJECTED'
GROUP BY product_order.product_id
ORDER BY COUNT(*) DESC, products.created_at
This statement returns the products that are not sold first because I am using left join and they count more than the sold ones.. also I don't know how to take the quantity in consideration
Thank you,
This should work :
SELECT p.*, sum(po.quantity) qty
FROM products p
LEFT OUTER JOIN product_order po ON po.product_id = p.id
LEFT OUTER JOIN orders o ON o.id = po.order_id
WHERE o.status != 'REJECTED'
GROUP BY po.product_id
ORDER BY qty DESC, p.created_at
If you want the most sold products you could add
AND products.quantity = SELECT max(quantity) from products
after your WHERE statement

different count from 2 tables

I have 3 tables as
products TABLE
FIELDS: productid, catid,...
sales TABLE
FIELDS: trackid, productid,...
promotion TABLE
FIELDS: trackid, productid,...
Now I need something like
ProductID CatID TotalSales TotalPromotion
1 1 10 3
How can I achieve this?
Thanks for the help
Join the above three tables.
Try this:
SELECT a.productid,
a.catid,
a.totalsales,
b.totalpromotion
FROM (SELECT p.productid,
p.catid,
COUNT(s.productid) AS totalsales
FROM products p
LEFT JOIN sales s
ON p.productid = s.productid
GROUP BY p.productid,
p.catid) a
INNER JOIN (SELECT p.productid,
p.catid,
COUNT(s.productid) AS totalpromotion
FROM products p
LEFT JOIN promotion s
ON p.productid = s.productid
GROUP BY p.productid,
p.catid) b
ON a.productid = b.productid
Hope this help,
select a.productID, a.catID,
b.totalSales, c.Totalpromotion from
Product a inner join Sales b on
a.catID=b.CatID inner join Promotion c
on a.CatID=C.CatID