How to find the earnings from the most sold product with sql? - sql

I have two tables:
I need to find the product name that was sold the most and the earnings from that.
The code I wrote:
SELECT *
FROM Products
WHERE ProductId = (SELECT ProductId
FROM
(SELECT
ProductId,
SUM(Quantity) AS total_order,
MAX(SUM(Quantity)) OVER () AS maxSm
FROM
Orders
GROUP BY
ProductId)
WHERE
total_order = maxSm)
But with this I just find the product name that was sold the most. Can you tell me please how can I find the earnings only from this product?

select top 1
a.name,
(b.total * a.price) as revenue
from
products a
left join (select productid, sum(quantity) as total group by productid) b
on a.productid = b.productid
order by
b.total desc

You need to join the result of your derived table to your Products table.
Without actual sample data I am unable to test, however the following should be what you need, or at least very close:
select p.Name, o.total_order, o.total_order * p.Price as TotalValue
from (
select * from (
select ProductId,
Sum(Quantity) as total_order,
Max(Sum(Quantity)) over () as maxSm
from Orders
group byProductId
)t
where total_order = maxSm
)o join Products p on p.ProductId=o.ProductId

Related

Include the sales revenue amount into the select query

I also have a (somewhat) similar scenario as from this guy.
This is my current code:
SELECT Vendor_Name, Product
FROM (
SELECT v.Vendor_Name, p.Description AS Product, ROW_NUMBER() OVER (PARTITION BY v.Vendor_Key ORDER BY SUM(sf.Price * sf.Quantity) DESC) AS seqnum
FROM SalesFacts sf JOIN Vendor v
ON sf.Vendor_Key = v.Vendor_Key JOIN Product p
ON sf.Product_Key = p.Product_Key
GROUP BY v.Vendor_Key, v.Vendor_Name, p.Product_Key, p.Description
) vp
WHERE vp.seqnum = 1
The result of the query is show as below:
What the above query did was to extract the top-grossing product for each vendor from the entire database, or in other words, the query obtained the highest-revenue product per vendor.
I wanted to add in a new column, which is Sales Revenue, which calculation can be derived as such:
price of item * quantity. I wanted to add in the new column so that i can see see how much revenue the vendor earned from their respective best-selling products.
How do i obtain the same result with the inclusion of sales revenue column?
The way your question is asked, you just want to return this column from the subquery so it can be accessed in the outer query:
SELECT Vendor_Name, Product, Sales_Revenue
FROM (
SELECT
v.Vendor_Name,
p.Description AS Product,
SUM(sf.Price * sf.Quantity) Sales_Revenue
ROW_NUMBER() OVER (PARTITION BY v.Vendor_Key ORDER BY SUM(sf.Price * sf.Quantity) DESC) AS seqnum
FROM SalesFacts sf JOIN Vendor v
ON sf.Vendor_Key = v.Vendor_Key JOIN Product p
ON sf.Product_Key = p.Product_Key
GROUP BY v.Vendor_Key, v.Vendor_Name, p.Product_Key, p.Description
) vp
WHERE vp.seqnum = 1

MS Access multiple joins with criteria

I'm generating an Inventory Query and the below code (mostly) works but it includes Invoices that have been voided, resulting in negative inventory.
Void Yes/No field = tblInvoices.Void
tblInvoiceDetails.InvoiceNum = tblInvoices.ID
I can't figure out how to ensure this does not include invoices that were voided. Thank you in advance for your help!
SELECT tblInventory.ID, Nz(sumTotalPaid,0)-Nz(sumCreditAmount,0) AS Quantity
FROM (tblInventory
LEFT JOIN (
SELECT ProductID, Sum(Quantity) AS sumTotalPaid
FROM tblOrderDetails
GROUP BY tblOrderDetails.ProductID
) AS sum1
ON tblInventory.ID = sum1.ProductID)
LEFT JOIN (
SELECT ProductID, Sum(Quantity) AS sumCreditAmount
FROM tblInvoiceDetails
GROUP BY tblInvoiceDetails.ProductID
) AS sum2
ON tblInventory.ID = sum2.ProductID;
Try it this way:
SELECT tblInventory.ID, Nz(sumTotalPaid,0)-Nz(sumCreditAmount,0) AS Quantity
FROM (tblInventory
JOIN (
SELECT ProductID, Sum(Quantity) AS sumTotalPaid
FROM tblOrderDetails
GROUP BY tblOrderDetails.ProductID
) AS sum1
ON tblInventory.ID = sum1.ProductID)
JOIN (
SELECT ProductID, Sum(Quantity) AS sumCreditAmount
FROM tblInvoiceDetails
WHERE tblInvoiceDetails.InvoiceNum IN
(SELECT tblInvoices.ID
FROM tblInvoices
WHERE tblInvoices.Void='Yes')
GROUP BY tblInvoiceDetails.ProductID
) AS sum2
ON tblInventory.ID = sum2.ProductID
1.- First you use just JOIN instead of LEFT JOIN, so you just get the rows that have values in both tables.
2.- You get only the Products that have the tblInvoices.Void='Yes'

SQL nested aggregate grouping error

I'm trying to find name of product which has sold maximum units, I've two tables, purchases and products, products has pname and pid, purchases has pid, qty(units sold).
I've managed this
select p.pname, sum(q.qty) from purchases q
inner join products p on p.pid=q.pid
where p.pid=q.pid
group by p.pname
order by sum(q.qty) desc
I'm getting the result in descending order but I need only the top most selling units, multiple products can have top most selling units. When I use
max(sum(q.qty))
I get grouping error.
One approach is to derive the values first using a common table expression.
Simply put you can't wrap aggregates in other aggregates. You may be able to wrap an aggregate around an analytic however.
with cte as (select p.pname, sum(q.qty) from purchases q
inner join products p on p.pid=q.pid
where p.pid=q.pid
group by p.pname
order by sum(q.qty) desc)
Select pname, max(purchases)
from cte
group by pname
You can use ctes to do this.
1)First get the total quantity of each product
2)Then get the maximum of all those totals
3)Join it with your original query
with totals as (select pid, sum(qty) totalqty from purchases group by pid)
, t1 as (select p.pid, p.pname, sum(q.qty) totqty
from purchases q
inner join products p on p.pid=q.pid
group by p.pname)
, t2 as (select max(totalqty) maxtotal from totals)
select pname, totqty
from t1
join t2 on t1.totqty = t2.maxtotal
Analytics can simplify this for you. If you have more than one product with the same sum(qty) and that happens to be the max(sum(qty)), then this should get you them:
select pname, quantity
FROM (
select p.pname
, sum(q.qty) quantity
,rank() over (order by sum(q.qty desc) ranking
from purchases q
inner join products p on p.pid=q.pid
group by p.pname
)
where ranking = 1

How do I select max date for each row from a subquery

Let's say I want to select the 3 bestsellers in a supermarket. To do this, I have to add each sale to get the total for each product:
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
It then returns me something like this:
ID..|.Name.|.totalsales
55.|.milk....|.1000
24.|.candy.|.800
67.|.juice...|.500
Now I want to retrieve a 4th column containing the last sale from each of these items, like querying "MAX saledate" to each one. How do I accomplish that?
EDIT: Adding MAX(s.saledate) isn't helping. It retrieves a date like 01 Jan 2012 to all rows, but if I query MAX(s.saledate) individually for each entry of the table above, it returns the correct date... My question is, how can I add the column MAX(s.saledate) for each product, using the same query that shows the 3 bestsellers.
You could add max(s.saledate) to your query. The subquery is not needed. The syntax t1 join t2 on <predicate> is considered much more readable than from t1, t2 where <predicate>.
select top 3 sum(s.individual_sale) as totalsales
, p.productID as ID,
, p.productName as Name
, max(s.saledate) as MaxSaleDate
from sales s
join products p
on p.productID = s.productID
group by
p.productID
, p.productName
order by
sum(s.individual_sale) desc
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(s.saledate) as MaxSaleDate
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
Add MAX(saledate) to your exisitng query.
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(saleDate)
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC

SQL Server query to find the total price of all the products by order

I have a table Orders with (id,orderCode,productId,quantity,color,size)
where I can have entries like:
1,O20100812,163,2,BLUE,Medium
1,O20100812,163,3,BLUE,Larger
1,O20100812,145,4,RED,Large etc
1,O20100815,134,5,RED,Large etc
1,O20100815,143,2,BLACK,Large etc
1,O20100815,112,8,BLACK,Large etc
And another table Products with (id,name,price)
What I want is to find the total price of all the products in the order with orderCode 020100812. Should I DISTINCT select the order code and then SUM the quantity while JOINing the products table?
Why you need distinct?
Select SUM(o.Quantity * Price) TotalPrice
FROM Orders o JOIN Products p ON (o.ProductId = p.Id)
WHERE OrderCode = '020100812'
For all orders you can use the following query:
Select OrderCode, SUM(o.Quantity * Price) TotalPrice
FROM Orders o JOIN Products p ON (o.ProductId = p.Id)
Group by OrderCode
No, GROUP BY and then you can use SUM to aggregate across the group, e.g.
select O.id, O.ordercode, sum(P.price * O.quantity) as total
from orders O
join products P on P.id = O.productid
group by O.id, O.ordercode
which will show you the total price for each order code within each order - if you wanted all order codes across all orders you'd need
select O.ordercode, sum(P.price * O.quantity) as total
from orders O
join products P on P.id = O.productid
group by O.ordercode
i.e. don't group in the order ID.
(I'm guessing that O20100812 was just an example and you actually want this for all order codes?)