Reputation: 69
I have Products table with discount like
productid discount
1 12
2 22
3 32
4 45
5 55
6 57
7 63
8 72
9 85
i want sql query for product count where discount 10%-100% or discount 20%-100% or discount 30%-100% or discount 40%-100% so on .. discount range
My sql query is
SELECT Count(product_id) AS product_count,
Substring_index(value_range, '-', 1) AS start,
Substring_index(value_range, '-', -1) AS END
FROM (SELECT product_id,
discount,
CASE
WHEN discount BETWEEN 80 AND 90 THEN '80-90'
WHEN discount BETWEEN 70 AND 90 THEN '70-90'
WHEN discount BETWEEN 60 AND 90 THEN '60-90'
WHEN discount BETWEEN 50 AND 90 THEN '50-90'
WHEN discount BETWEEN 40 AND 90 THEN '40-90'
WHEN discount BETWEEN 30 AND 90 THEN '30-90'
WHEN discount BETWEEN 20 AND 90 THEN '20-90'
WHEN discount BETWEEN 10 AND 90 THEN '10-90'
END AS value_range
FROM products) AS T2
GROUP BY value_range
ORDER BY Cast(start AS UNSIGNED) ASC
but it not giving desire result expected result is
discount_range countproduct
10%-100% 9
20%-100% 8
30%-100% 7
40%-100% 6.. so on
Here is My output.
Upvotes: 0
Views: 317
Reputation: 5803
If you don't want to create a second table, try building off of this:
select "10%-100%" as discount_range, (select count(*) from products where discount between 10 and 100) as product_count
union
select "20%-100%" as discount_range, (select count(*) from products where discount between 20 and 100) as product_count
union
select "30%-100%" as discount_range, (select count(*) from products where discount between 30 and 100) as product_count
union
select "40%-100%" as discount_range, (select count(*) from products where discount between 40 and 100) as product_count
Upvotes: 0
Reputation: 692
try this one
select
x.bin,
x.bin_count,
sum(y.bin_count) as cumulative_count
from
( select
floor(discount / 10) as lower_bound,
concat('[', floor(discount / 10) * 10, ' - ', floor(discount / 10) * 10 + 10, ')') as bin,
count(*) as bin_count
from
t1
group by
1, 2) as x
join ( select
floor(discount / 10) as lower_bound,
concat('[', floor(discount / 10) * 10, ' - ', floor(discount / 10) * 10 + 10, ')') as bin,
count(*) as bin_count
from
t1
group by
1, 2) as y on x.lower_bound >= y.lower_bound
group by
1, 2
one more
select
x.bin,
x.bin_count,
concat('[', min(y.lower_bound), ' - ', max(y.upper_bound), ')') as cumulative_bin,
sum(y.bin_count) as cumulative_count
from
( select
floor(discount / 10) * 10 as lower_bound,
floor(discount / 10) * 10 + 10 as upper_bound,
concat('[', floor(discount / 10) * 10, ' - ', floor(discount / 10) * 10 + 10, ')') as bin,
count(*) as bin_count
from
t1
group by
1, 2, 3) as x
join ( select
floor(discount / 10) * 10 as lower_bound,
floor(discount / 10) * 10 + 10 as upper_bound,
concat('[', floor(discount / 10) * 10, ' - ', floor(discount / 10) * 10 + 10, ')') as bin,
count(*) as bin_count
from
t1
group by
1, 2, 3) as y on x.lower_bound >= y.lower_bound-- order by 1, 5
where
x.lower_bound >= 10
and y.lower_bound >= 10
group by
x.bin
Upvotes: 0
Reputation: 164224
You need a query that counts the products inside the query that groups by range:
select
concat(t.floorvalue, '%-90%') discount_range,
t.countproduct
from (
select
floor(p.discount / 10) * 10 floorvalue,
(select count(*) from products where discount >= floorvalue) countproduct
from products p
group by floorvalue
) t
order by discount_range
See the demo.
Results:
| discount_range | countproduct |
| -------------- | ------------ |
| 10%-90% | 9 |
| 20%-90% | 8 |
| 30%-90% | 7 |
| 40%-90% | 6 |
| 50%-90% | 5 |
| 60%-90% | 3 |
| 70%-90% | 2 |
| 80%-90% | 1 |
Upvotes: 0
Reputation: 48207
First you need create a table for your ranges:
CREATE TABLE Ranges
(`start` int, `end` int)
;
INSERT INTO Ranges
(`start`, `end`)
VALUES
(10, 100),
(20, 100),
(30, 100),
(40, 100),
(50, 100),
(60, 100),
(70, 100),
(80, 100),
(90, 100)
;
Then just found on what ranges each product discount is part of:
SELECT `start`, `end`, `productid`, `discount`
FROM ranges
LEFT JOIN products
ON products.discount between `start` and `end`
Then just count it:
SELECT `start`, `end`, COUNT(`productid`)
FROM (
SELECT `start`, `end`, `productid`, `discount`
FROM ranges
LEFT JOIN products
ON products.discount between `start` and `end`
) t
GROUP BY `start`, `end`
ORDER BY `start`
OUTPUT
| start | end | COUNT(`productid`) |
|-------|-----|--------------------|
| 10 | 100 | 9 |
| 20 | 100 | 8 |
| 30 | 100 | 7 |
| 40 | 100 | 6 |
| 50 | 100 | 5 |
| 60 | 100 | 3 |
| 70 | 100 | 2 |
| 80 | 100 | 1 |
| 90 | 100 | 0 |
Upvotes: 1