Reputation: 5385
Given a set of random numeric values in a database, how do I generate a limited list of ranges where each range contains at least one value? The ranges should not overlap and ideally have a similar amount of values in them. Ideally their boundaries should also be multiples of 10, 100, 1000 etc...
For example:
Values: 100,150,180,300,400,500,600,650,700 results in 4 ranges: 100-180(2), 180-300(1), 300-600(3), 600-800(3)
How could this be done in C# or T-SQL?
Upvotes: 2
Views: 1016
Reputation: 425261
In MS SQL 2005+
:
SELECT range, (MIN(getprev) + MIN(value)) / 2 as range_start, (MAX(getnext) + MAX(value)) / 2 AS range_end, COUNT(*) as range_values
FROM (
SELECT value,
NTILE(4) OVER (ORDER BY value ) AS range,
(
SELECT TOP 1 value
FROM values li
WHERE li.value < lo.value
ORDER BY
li.value DESC
) AS getprev,
(
SELECT TOP 1 value
FROM values li
WHERE li.value > lo.value
ORDER BY
li.value
) AS getnext
FROM values lo
) vo
GROUP BY range
ORDER BY range
In your case:
1 100 240 3 2 240 450 2 3 450 625 2 4 625 700 2
Upvotes: 2
Reputation: 17964
Assume we want ranges with one value in them each: Values: 100 150 180 300 Just produce these random numbers:
- a: 0 <= 100, eg: 50
- b: 100 <= 150, eg: 125
- c: 150 <= 180, eg: 165
- d: 180 <= 300, eg: 200
- e: 300 <= , eg: 350
...
Ranges:
50-125 (1), 125-180(1), 180-200(1), 200 - 350 (1) ...
: each one contains exactly one number.
Now to have more then one number in each range, just start skippin numbers, for example skip c (can pick a random chance to skip one): skip c:
50-125(1), 125-200(2), 200-350(1)
Upvotes: 0