Как динамически генерировать группы / группы данных с одинаковыми номерами в каждой? - PullRequest
2 голосов
/ 23 декабря 2010

Я хочу динамически генерировать полосы, которые затем будут сгруппированы в отчетах.

Моей первой мыслью было сгенерировать полосы, взяв минимальное значение и максимальное значение, а затем разделив разницу.

Например, предположим, у вас была зарплата для большой группы людей:

  • Самая низкая заработная плата зарабатывает £ 12 000 в год, а самая высокая зарабатывает £ 3 000 000
  • Так что я разделил этона 10 групп одинакового размера: (£ 3mill - £ 12k) / 10 = £ 298800
  • Так что моя первая группа идет от £ 12k до 310,800 и получает тысячи людей
  • Мой второйгруппа идет от £ 310 000 до £ 610 000 и имеет несколько сотен
  • В каждой другой группе есть несколько человек в каждой

Так что на самом деле это не очень полезно.Если бы мне пришлось создавать группы вручную, я бы хотел примерно одинаковые числа в каждой, что-то вроде: £ 12k-£ 14k, £ 14k-£ 18k, £ 18k-£ 25k, £ 25- £ 35k, ..., £1,5–3 миллиона фунтов стерлингов

Это всего лишь один пример - может быть много разных дистрибутивов.

Я ищу алгоритм для генерации полос, чтобы пользователи могли указать, сколько полос они хотят, и данные будут сгруппированы в такое количество полос с одинаковым числом в каждой.

Объединение должно быть быстрым - я не могу просто пройтись по всему набору данных.

Приложение на C # поверх SQL, но решения из других языков приветствуются.

Ответы [ 4 ]

3 голосов
/ 23 декабря 2010

Вы смотрели на NTILE ?SQL Server и большинство dbms поддерживают его.

Например:

select b.band, count(*), min(b.valuefield), max(b.valuefield)
from ( 
    select ntile(10) over (order by valuefield) as 'band', valuefield
    from table ) b
group by b.band
2 голосов
/ 23 декабря 2010

Вы смотрите на проблему с неправильной точки зрения. Вместо того, чтобы смотреть на зарплату, посмотрите на упорядоченную позицию человека в отсортированном диапазоне зарплат. Отложите алгоритм на секунду и подумайте об этом математически.

Бери всех своих людей и сортируй их по зарплате. Теперь последовательно перечислите их от 1 до n, последний с самой высокой зарплатой. Если вам нужно m групп, то каждая группа содержит н / м человек. Таким образом, первый диапазон окладов переходит от 0 до человека [н / м]. Зарплата, от второго до человека [2 * н / м].

В C # вы можете сделать это довольно эффективно в Linq. Что-то вроде этого. Это непроверенный код, это концепция, а не окончательное решение, возможно, есть некоторые проблемы с граничными условиями, о которых я не задумывался.

List<int> GetBands(int numBands)
{
    using(var db = new MyContext())    
    {
        var list SalaryBands = new List<int>();
        var count = db.People.Count();
        var salaries = db.People.OrderBy(item => item.Salary)
                                .Select(item => item.Salary);
        int skipCount = count / numBands;
        for(int segmentNum = 0; segmentNum < numBands; segmentCount++)
        {
            salaries = salaries.Skip(skipCount);
            salaryBands.Add(salaries.First());
        }
        return salaryBands;
    }
}
1 голос
/ 23 декабря 2010

Я думаю, что вы спрашиваете о том, как запросить существующий набор данных в «диапазоны» ...

, если это так, то Oracle поддерживает агрегатные функции NTILE для этой цели.В других реализациях SQL должны быть эквиваленты.

0 голосов
/ 23 декабря 2010

Первое наблюдение, вам нужен логоподобный график, а не прямолинейный.

Второе наблюдение: я обычно строю большие выборочные наборы данных (сродни вашему примеру), а затем ищу общие факторывывести формульную систему из фактических данных.Можете ли вы представить еще несколько сценариев?

...