Percentage of the total revenue - sql

I have category, Sub-category and Revenue.
Category Sub-Category Revenue Percentage
---------------------------------------------------------
Books Text Books 5000 (5000/14000)*100
Comics Books 6000
Horror Books 3000
Now my question is, how to achieve like this using SQL?
I need percentage wrt to total sales for that category.

Oracle has RATIO_TO_REPORT analytic function, which computes the ratio of a value to the sum of a set of values.
select category, subcategory, revenue,
round((ratio_to_report(revenue) over (partition by category) * 100),2) as percentage
from mytable;
Output:
CATEGORY SUBCATEGORY REVENUE PERCENTAGE
-----------------------------------------
books text 5000 35.71
books horror 3000 21.43
books comics 6000 42.86
Sample fiddle here

You can use an analytical SUM function:
select
Category,
SubCategory,
Revenue,
Revenue * 100 / sum(Revenue) over (partition by Category) as Percentage
from
yourTable
;

You can use a subselect to get the overall revenue and use it in the calculations.
SELECT category, sub-category, revenue,
((revenue /
SELECT sum(inne.revenue)
FROM table inne
WHERE inne.category = oute.category) * 100) AS percentage
FROM table oute

Related

Oracle SQL: How to calculate AVG on case-sensitive columns?

I need to calculate the average price per brand of the table below:
SELECT * FROM VENDOR;
Expected result:
I did some tests but they do not calculate and group the AVG per brand,
For example:
CREATE VIEW AVERAGE_PRICE AS
SELECT LOWER (BRAND) as BRAND, AVG (PRICE) as PRICE
FROM VENDOR
GROUP BY BRAND;
Any ideas?
Should be
group by lower(brand)

SQL (DB2) query to get count of top 10% revenue contributing customers

I work for a telecom company and I need to run a scheme for top valued customers who contributed 10% of total company's revenue in the month. I want to know the count of customers who are eligible for this scheme? I am using SQL DB2.
Ex - In the below table, Sum of the Revenue is 5000 and its 10% is 500, and I want to know the count of minimum number of customers whose sum of revenue would be either 500 or just above 500
Customers Revenue
A 156
B 259
C 389
D 125
E 578
F 321
To find all customers where their total revenue is at least 10 percent of the overall revenue:
select customer
from the_table
group by customer
having sum(revenue) >= (select sum(revenue) * 0.1 from the_table);
Your sample data doesn't show this, but this also deals with multiple rows per each customer in the table (your example only has a single row per customer)
The get the count of that:
select count(*)
from (
select customer
from the_table
group by customer
having sum(revenue) >= (select sum(revenue) * 0.1 from the_table)
) t
I interpret the question as wanting the highest revenue customers whose sum is at least 10% of the total revenue.
You need a cumulative sum for this:
select count(*)
from (select t.*, sum(revenue) over (order by revenue desc) as cume_rev,
sum(revenue) over () as tot_rev
from t
) t
where cume_rev <= tot_rev * 0.1;
This assumes that there is one row per customer.
EDIT:
For "just above", the where clause should be:
where cume_rev - revenue < tot_rev * 0.1;

profit for products

I d like to create a query gives me Overall revenue per product greater than 150000 in in descending order. You can see my tables and desired output on images I have added
Whats not clear from your question is how you want to calculate revenue. Assuming that revenue per product is calculated as unit price x quantity from the Order_Items table:
SELECT product_id, SUM(unit_price * quantity) AS revenue
FROM Order_Items
GROUP BY product_id
HAVING SUM(unit_price * quantity) > 150000
ORDER BY revenue DESC

Find the areaid that sells most number of products but with less discount

I am pretty new to SQL Server.
I have a question on one of the queries that I am trying to come up with
I have a table like this:
pid areaid units discount
-------------------------
1 1 10 10%
2 1 20 10%
3 2 30 5%
4 2 40 15%
5 1 50 10%
6 3 10 0%
I am trying to find the areaid that sells most number of products(units) but with less discount.
I tried some query as below but I couldn't figure out a way to join the below 2 queries.
I was able to find the least discount using the below query
select
min(y.discount)
from
(select
sum(discount) as discount
from
productinfo
group by
areaid) y
but not sure how to get the area id corresponding to that aggregated discount.
Similarly I figured out a query to return maximum number of products aggregated by areaid
select
max(y.uomsum)
from
(select
sum(uom) as uomsum
from
productinfo
group by
areaid) y
It would be great if anyone can help me with this query.
select areaid, MAX(TotalUnits), MIN(TotalDiscount)
FROM
(
select areaid , SUM(units) as TotalUnits, SUM(discount) TotalDiscount
from Table1
group by areaid
)T
group by areaid
May be something like this
SELECT MIN(Y.Discount),MAX(Y.Units)
FROM
(SELECT AreaID,SUM(Discount) AS Discount ,SUM(units) as Units
FROM productinfo
GROUP BY Areaid
) Y
It seems to me, that you need to calculate the average discount per area discount, then sum.
Select
sum(discountedUnits), areaid
from (
select
sum(units) as units,
sum(units) * (1-(convert(float, discount)/100)) as discountedUnits,
convert(float, sum(units) * (1-(convert(float, discount)/100))) / sum(units) as averageUnit,
areaid,
discount
from
productinfo
group by areaid, discount) as g
group by areaid
Here's a fiddle
To get the max, you could do a top 1 and order by descending, or put it all in another subselect

Multiple WHERE OR Expression in query using SQL Server

I have here the Query to Select Multiple Expression
SELECT * FROM tbProducts WHERE
(PRICE BETWEEN 4590 AND 5100) AND RATING = (SELECT MAX(RATING) FROM tbxProducts) AND
(PRICE = (SELECT MAX(PRICE) FROM tbxProducts))
These are the columns from tbProdcts
| PRODUCT_NAME | DESCRIPTION | RATING | PRICE |
but the problem is that the table cannot display any Items with the range of 4590 up to 5100
And after that. I would select also the max rate of an items and max Price with that Range of Price
how can I do it with the right query?
Thanks in Advanced :)
This should do what you're asking for in a somewhat more straight forward manner.
It will return the item with the highest rating. If there are multiple items with the same highest rating, it will use the highest price as a tie breaker.
SELECT TOP 1 *
FROM tbProducts
WHERE price BETWEEN 4590 AND 5100
ORDER BY rating DESC, price DESC
you need to limit the output of
SELECT MAX(PRICE) FROM tbxProducts
so something like
SELECT MAX(PRICE) FROM tbxProducts t where t.PRICE BETWEEN 4590 AND 5100