In the table category I replace the Range with the spread (max - min), which is more usable in a query that a string with a iphen in it.
I added a lso a Catergory order to determine the order of overflow, its called CategoyOrder
Try this and let us know please:
/************* DATA SOURCE **********************/
IF OBJECT_ID('tempdb..#sales') IS NOT NULL
DROP TABLE #sales;
CREATE TABLE #sales
(
year_month VARCHAR(10),
total_sales INT
);
INSERT INTO #sales
(
year_month,
total_sales
)
VALUES
('2019-10-01', 557361),
('2019-11-01', 621801);
select * from #sales
IF OBJECT_ID('tempdb..#categories') IS NOT NULL
DROP TABLE #categories;
CREATE TABLE #categories
(
CategoryOrder int ,
Category VARCHAR(10),
price decimal(5,2),
discount decimal(5,2),
RangeSpread int ,
CumulRangeSpread int
);
INSERT INTO #categories
(
CategoryOrder,
Category,
price,
discount,
RangeSpread,
CumulRangeSpread
)
VALUES
(1,'Small', 15, 0, 50000, 50000),
(2,'Medium', 13, 15, 350000, 400000),
(3,'Big', 11, 25, 400000, 800000);
select * from #categories
/************* END *****************/
/************* QUERY *****************/
;with cte as
(select c1.CategoryOrder, c1.Category, c1.price, c1.discount, c1.RangeSpread, isnull(c2.CumulRangeSpread, 0) as CumulRangeSpread from #categories c1 left join #categories c2 on c1.CategoryOrder -1 = c2.CategoryOrder)
select c.CategoryOrder, c.Category, c.price, c.discount, total_sales,
case when c.RangeSpread < total_sales - CumulRangeSpread then c.RangeSpread else total_sales - CumulRangeSpread end as [CountIncategory],
c.price*(case when c.RangeSpread < total_sales - CumulRangeSpread then c.RangeSpread else total_sales - CumulRangeSpread end) as [Count*Price]
from cte c cross join #sales s order by total_sales, 2 desc