Frage

Ich möchte dynamisch Bänder generieren, die dann in Berichten gruppiert werden.

Mein erster Gedanke war, die Bänder zu erzeugen, indem der Mindestwert und den Maximalwert genommen und dann die Differenz aufgeteilt wurde.

Angenommen, Sie hatten die Gehälter für eine große Gruppe von Menschen:

  • Der niedrigste bezahlte verdient £ 12.000 pro Jahr und der höchste verdient 3.000.000 Pfund Sterling
  • Also habe ich das in 10 Bänder mit ähnlicher Größe aufgeteilt: (£ 3mill - £ 12k) / 10 = £ 298800
  • Also gilt meine erste Band £ 12.000 bis £ 310.800 und bekommt Tausende von Menschen darin
  • Meine zweite Band geht £ 310.000 bis £ 610.000 und hat ein paar hundert
  • Jede andere Band hat ein paar Leute in jedem einzelnen

Das ist also nicht sehr nützlich. Wenn ich die Bands manuell erstellen würde, würde ich in jeweils ungefähr ähnliche Zahlen wollen, ungefähr: £ 12k- £ 14k, £ 14k- £ 18k, £ 18k- £ 25k, £ 25- £ 35K, ..., £ 1,5- £ 3 Millionen

Dies ist nur ein Beispiel - es könnte viele verschiedene Verteilungen geben.

Ich suche nach einem Algorithmus, um die Bänder zu generieren, sodass Benutzer eingeben, wie viele Bands sie wollen, und die Daten würden in so viele Bands mit einer ähnlichen Zahl in jeweils gegründet.

Das Streifen muss schnell sein - ich kann nicht einfach den gesamten Datensatz durchlaufen.

Die Anwendung ist C# über SQL, aber Lösungen aus anderen Sprachen willkommen.

War es hilfreich?

Lösung

Ich denke, Sie fragen nach dem Abfragen eines vorhandenen Datensatzes in die "Bands" ...

Wenn dies zutrifft, unterstützt Oracle ntile Aggregatfunktionen für den Zweck. In anderen SQL -Implementierungen sollten Äquivalente vorhanden sein.

Andere Tipps

Hast Du Dir angesehen Ntile? SQL Server und die meisten DBMs unterstützen es.

Zum Beispiel:

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

Sie betrachten das Problem aus falscher Sicht. Anstatt sich das Gehalt anzusehen, betrachten Sie die geordnete Position der Person in der sortierten Gehälter. Legen Sie den Algorithmus für eine Sekunde beiseite und denken Sie mathematisch darüber nach.

Nehmen Sie alle Ihre Leute und sortieren Sie sie nach Gehalt. Zählen Sie sie nun nacheinander von 1 auf bis n, dem letzten mit dem höchsten Gehalt. Wenn Sie M -Gruppen benötigen, enthält jede Gruppe N/M -Personen. Das erste Gehaltsband geht also von 0 bis zur Person [n/m] .Salary, das zweite von dort zu Person [2*n/m] .Salary und so weiter.

In C# können Sie dies in Linq ziemlich effizient tun. Etwas wie das. Dies ist ein ungetesteter Code, dies ist ein Konzept, das keine endgültige Lösung ist. Es gibt wahrscheinlich einige Probleme mit der Kantenbedingung, über die ich nicht richtig nachgedacht habe.

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;
    }
}

Erste Beobachtung, Sie möchten ein logarithmisch ähnliches Diagramm im Gegensatz zu geraden Linear.

Zweite Beobachtung: Ich baue normalerweise große Beispieldatensätze (ähnlich wie bei Ihrem gegebenen Beispiel) und suche dann nach meinen gemeinsamen Faktoren und leite ein formelhaftes System aus den tatsächlichen Daten ab. Können Sie noch einige Szenarien punkten?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top