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
Related
I am trying to add a new column to my table which will be the average value calculated as the division of two existing columns. Therefore Average value = Total Sales / Number of Orders.
My data looks like this:click to view picture
I don't understand why Example Code A does not work but Example Code B does. Please can someone explain?
Example Code A
%%sql
SELECT
c.country,
count(distinct c.customer_id) customer_num,
count(i.invoice_id) order_num,
ROUND(SUM(i.total),2) total_sales,
order_num / total_sales avg_order_value
FROM customer c
LEFT JOIN invoice i ON c.customer_id = i.customer_id
GROUP BY 1
ORDER BY 4 DESC;
Example Code B
%%sql
WITH
customer_sales AS
(
SELECT
c.country,
count(distinct c.customer_id) customer_num,
count(i.invoice_id) order_num,
ROUND(SUM(i.total),2) total_sales
FROM customer c
LEFT JOIN invoice i ON c.customer_id = i.customer_id
GROUP BY 1
ORDER BY 4 DESC
)
SELECT
country,
customer_num,
order_num,
total_sales,
total_sales / order_num avg_order_value
FROM customer_sales;
Thank you!
Depending on the DBMS some allow you to reference the alias in the calculation (in the same select) and others require you to either bring it outside in an outer query or state your previous aggregation/functions, such as counts or sums.
SELECT
c.country,
count(distinct c.customer_id) customer_num,
count(i.invoice_id) order_num,
ROUND(SUM(i.total),2) total_sales,
count(i.invoice_id) / ROUND(SUM(i.total),2) avg_order_value
FROM customer c
LEFT JOIN invoice i ON c.customer_id = i.customer_id
GROUP BY 1
ORDER BY 4 DESC;
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
How do I obtain the top-grossing product for each individual vendor?
I came up with this so far and can't seem to proceed.
select vendor.Vendor_Name, Product.category AS Product
, SUM(SalesFacts.Price * SalesFacts.Quantity) AS [Total Revenue]
FROM Vendor, Product, SalesFacts
WHERE SalesFacts.Vendor_Key = Vendor.Vendor_Key
AND SalesFacts.Product_Key = Product.Product_Key
GROUP BY vendor.Vendor_Name, product.Category
ORDER BY [Total Revenue] DESC;
(Product_Key and Vendor_Key are Foreign Key)
select vendor.Vendor_Name,Product.category AS Product,
MAX(SalesFacts.Price * SalesFacts.Quantity) OVER (PARTITION BY
SalesFacts.Vendor_Key,SalesFacts.Product_Key ORDER BY SalesFacts.Vendor_Key ) AS
[Total Revenue] FROM Vendor
,Product,SalesFacts WHERE SalesFacts.Vendor_Key = Vendor.Vendor_Key AND
SalesFacts.Product_Key = Product.Product_Key
--GROUP BY vendor.Vendor_Name,product.Category,SalesFacts.Price,SalesFacts.Quantity
ORDER BY [Total Revenue] DESC;
You can use this.
SELECT * FROM (
SELECT
vendor.Vendor_Name,
Product.Category AS Product,
ROW_NUMBER() OVER(PARTITION BY vendor.Vendor_Name ORDER BY SUM(SalesFacts.Price * SalesFacts.Quantity) DESC) RN
FROM Vendor
INNER JOIN SalesFacts ON SalesFacts.Vendor_Key = Vendor.Vendor_Key
INNER JOIN Product ON SalesFacts.Product_Key = Product.Product_Key
GROUP BY vendor.Vendor_Name, product.Category
) X
WHERE X.RN = 1
I don't see why a "category" should be a product. More importantly, you should be fixing your query:
Never use commas in the FROM clause.
Always use proper, explicit, standard JOIN syntax.
Use meaningful table aliases.
At the product level, this would be:
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;
This can be easily modified to work for the category, but the question says "product" and the data has something that corresponds to that.
I have three tables:
Customer(IdCustomer, Name)
Product(IdProduct, Product)
Order(IdProduct, IdCustomer, nbOrders)
So the Order table stores how many times a customer has ordered a product.
I need a view like this:
TopOrder(Name, Product, nbCommands)
But I only want 10 products for each customer, the ones he ordered the most and I can't figure it out.
The dense_rank window function should be exactly what the doctor prescribed:
CREATE View TopOrder AS
SELECT Name, Product, nbOrders
FROM (SELECT Name, Product, nbOrders,
DENSE_RANK() OVER (PARTITION BY o.idCustomer
ORDER BY nbOrders DESC) AS rk
FROM Customer c
JOIN Orders o ON c.idCustomer = o.idCustomer
JOIN Product p ON p.idProduct = o.idProduct
) t
WHERE rk <= 10
I am trying to join 2 tables and create a new field returning the lowest value of a product. I've tried many variations and can't seem to get it to work.
SELECT DISTINCT VENDOR.*, PRODUCT.P_PRICE, PRODUCT.LOWEST_PRICE AS MIN(PRODUCT.P_PRICE)
FROM PRODUCT
INNER JOIN VENDOR
ON VENDOR.V_CODE = PRODUCT.V_CODE
ORDER BY VENDOR.V_NAME
You can use this, This will order from Minimum price vendor product
SELECT VENDOR.V_NAME, MIN(PRODUCT.P_PRICE) AS LOWEST_PRICE
FROM VENDOR
INNER JOIN PRODUCT
ON VENDOR.V_CODE = PRODUCT.V_CODE
GROUP BY VENDOR.V_NAME
ORDER BY LOWEST_PRICE
SQL FIDDLE:- http://sqlfiddle.com/#!3/467c8/2
If you are looking for the lowest price by vendor, use group by and min:
SELECT VENDOR.V_NAME, MIN(PRODUCT.P_PRICE) AS LOWEST_PRICE
FROM PRODUCT
INNER JOIN VENDOR
ON VENDOR.V_CODE = PRODUCT.V_CODE
GROUP BY VENDOR.V_NAME
ORDER BY VENDOR.V_NAME
Not knowing how your schema is defined try this:
SELECT
VENDOR.V_NAME,
PRODUCT.P_PRICE AS [VENDOR PRICE],
MIN(PRODUCT.P_PRICE) AS [LOWEST PRICE]
FROM
PRODUCT
INNER JOIN VENDOR ON VENDOR.V_CODE = PRODUCT.V_CODE
GROUP BY
VENDOR.V_NAME,PRODUCT.P_PRICE
ORDER BY
VENDOR.V_NAME
If you want the lowest price product per vendor, I would suggest using window functions:
select pv.*
from (select v.v_name, p.p_name, p.p_price
row_number() over (partition by p.v_code order by p.p_price asc) as seqnum
from vendor v join
product p
on v.v_code = p.v_code
) pv
where seqnum = 1