CREATE TABLE `new_table` ( `start` int NOT NULL, `length` int NOT NULL ); INSERT INTO `new_table` VALUES (5, 6), (11, 1), (21, 10), (11, 8), (13, 18);
How the following result appears when creating a table as above.
|-----------|----------| | 1~10 | 1 | |-----------|----------| | 11~20 | 4 | |-----------|----------| | 21~30 | 2 | |-----------|----------| | 31~40 | 2 |
This is the result of counting if the value is included between start plus length.
e.g. : start=5, length=6
This means 5(start)~11(start+lenght)
5<=10 is true
1~10 + 1
11<=20 is true
11~20 + 1
e.g. : start=21, length=10
This means 21(start)~31(start+lenght)
21<=30 is true
21~30 + 1
31<=40 is true
31~40 + 1
e.g. : start=13, length=18
This means 13(start)~31(start+lenght)
(13-20) between (13-31) is included in numbers less than 20.
11~20 + 1
(21-30) between (13-31) is included in numbers less than 30.
21~30 + 1
31 between (13-31) is included in numbers less than 30.
30~40 + 1
I’ve seen how to implement this via googling, but in the end I didn’t get the result. So I tried to implement it further, but it was not enough for me.
Ask for help
Thank you!
Advertisement
Answer
Are you trying to categorize (start + length
) into different groups? If so, you can do something like this:
SELECT '>=' || TRIM(length_group), COUNT(*) FROM ( SELECT CASE WHEN total_length >= 40 THEN '40' -- Evaluate to true for first match WHEN total_length >= 30 THEN '30' WHEN total_length >= 20 THEN '20' WHEN total_length >= 10 THEN '10' END AS length_group FROM new_table ) src GROUP BY length_group
Update
I think I understand what you’re trying to get now. You want to get the ranges of which your (start + length)
interval falls into. Is that correct? If so, give this a try:
WITH intervals(start, end) AS ( SELECT 1, 10 UNION ALL SELECT 11, 20 UNION ALL SELECT 21, 30 UNION ALL SELECT 31, 40 ) SELECT val_group, COUNT(*) AS group_count FROM ( SELECT CONCAT(CAST(iv.start AS CHAR(3)), '~', CAST(iv.end AS CHAR(3))) AS val_group, iv.start FROM new_table src INNER JOIN intervals iv ON src.start BETWEEN (iv.start - src.length) AND iv.end ) src GROUP BY val_group ORDER BY MAX(start), group_count ;
It would be much easier using native data types / functions like INTERVAL
and OVERLAP
, but it doesn’t seem like MySql
has that functionality yet.