2015-05-05 13 views
7

Ich habe eine SQL-Abfrage, die Teilnehmer nach mehreren Feldern sortiert. Ich muss dies in LINQ konvertieren, was ich verstehe, hat keine Rangfunktion. Kann jemand helfen, dies zu konvertieren?SQL-Rang in LINQ zu Entitäten

Wenn es hilft, hier ist das, was es tut. Diese Abfrage ruft Teilnehmer aus einer Tabelle ab und ordnet sie basierend auf den aufgelisteten Feldern RANK() OVER (ORDER BY W desc, L asc, RW asc, RL desc, HP desc, TB desc) AS RANK zu. Weiter packe ich nur irgendwelche Verbindungen für diese beiden Rankings sind, wenn jene auf Platz 1 oder 2 Where q1.RANK in ('1','2') und sehen Having count(q1.ParticipantID) > 1

Select q1.RANK, count(q1.ParticipantID) as 'Count' 
From (
     Select Distinct ParticipantID, RANK() OVER (ORDER BY W desc, L asc, RW asc, RL desc, HP desc, TB desc) AS RANK 
     From vGroupStandings 
     Where CompetitionID = 8 
     and GroupNumber = 1 
     and EventID = 6 
    ) as q1 
Where q1.RANK in ('1','2') 
Group By q1.RANK 
Having count(q1.ParticipantID) > 1 

UPDATE

Hier werden die Daten der Auswahl alle Felder

enter image description here

Hier ist ein Beispiel dafür, wie die gefilterten Daten in der Unterabfrage aussehen. Von diesem Satz, schaue ich zu sehen, wenn es mehr als 1 Datensatz ist auf Rang 1 oder Rang 2.

enter image description here

RESPONSE

Danke für die Antworten so weit, auf Platz lasse ich Sie wissen, wann ich diese ausprobieren kann. Hier ist eine andere Frage. Wäre es besser, stattdessen eine gespeicherte Prozedur von einem Controller aufzurufen? Auf diese Weise kann ich die SQL-Abfrage so lassen, wie sie ist. Ich habe eine Reihe von großen Abfragen, die ich ausführen muss, die Rang beinhalten. Ich frage mich, ob es einfacher wäre, alles in LINQ neu zu schreiben.

+0

Ich versuchte Linqer mit (das wird SQL zu LINQ konvertieren für dich) und das sagt mir RANK() Konvertierung wird nicht unterstützt. Ich bin ziemlich neu bei Linq und das ist komplexer, als ich jetzt verarbeiten kann. – madvora

+0

@Hogan, der Partitionsteil ist optional – Alex

+0

ok ich sehe - es verwendet die Elemente in der Reihenfolge, um zu finden, Krawatten. – Hogan

Antwort

1

So etwas ... das ist Pseudocode .... Ich habe nicht getestet.

Wenn Sie beispielsweise Daten gab und erwartete Ausgabe dann würde ich tun, so

var inner = datasource 
       .OrderByDesc(x => x.W) 
       .ThenBy(x => x.L) 
       // etc for all orders you need 
       .GroupBy(new { W = W, L = L, RW = RW, RL = RL, HP = HP, TB = TB }) 
       .First(2); 

if (inner[0].Count > 1 || inner[1].Count[1] > 1) 
{ 
    Console.Writeline("1 "+inner[0].Count.ToString()); 
    Console.Writeline("2 "+inner[1].Count.ToString()); 
} 
+0

OK, ich habe ein Update hinzugefügt, damit Sie ein visuelles Gefühl dafür haben, wovon ich rede. Das Ergebnis wäre nur unten filtern, dass die Unterabfrage, ob es irgendwelche Verbindungen auf Rang 1 oder 2. In diesem Fall würde das Abfrageergebnis leer sein (da es keine Bindungen). – madvora

+0

@Madvora - bekam alles. Dies ist auch der Code oben. – Hogan

2

Diese ziemlich hässlich ist, aber für mich funktioniert dieses Beispiel-Klasse.

public class Participant 
{ 
    public int Id { get; set; } 
    public int Score1 { get; set; } 
    public int Score2 { get; set; } 
    public int ExpectedRank { get; set; } 
} 

Auf dieser Sammlung:

var participants = new Participant[] { 
    new Participant { Id = 1, Score1 = 2, Score2 = 5, ExpectedRank = 6 }, 
    new Participant { Id = 2, Score1 = 10, Score2 = 8, ExpectedRank = 1 }, 
    new Participant { Id = 3, Score1 = 7, Score2 = 2, ExpectedRank = 4 }, 
    new Participant { Id = 4, Score1 = 7, Score2 = 4, ExpectedRank = 3 }, 
    new Participant { Id = 5, Score1 = 7, Score2 = 2, ExpectedRank = 4 }, 
    new Participant { Id = 6, Score1 = 7, Score2 = 7, ExpectedRank = 2 }, 
}; 

durch die folgende ziemlich hässlich LINQ-Abfrage zu tun:

var ranked = participants 
    .OrderByDescending(p => p.Score1) 
    .ThenByDescending(p => p.Score2) 
    .Select((p, i) => new { Order = 1 + i, Participant = p }) 
    .GroupBy(p => new { p.Participant.Score1, p.Participant.Score2 }) 
    .SelectMany(g => g.Select(p => new { 
     Id = p.Participant.Id, 
     Rank = g.Min(x => x.Order), 
     ExpectedRank = p.Participant.ExpectedRank 
    })); 

foreach (var p in ranked) 
    Console.WriteLine(p); 

, die die folgende Ausgabe erzeugt:

{ Id = 2, Rank = 1, ExpectedRank = 1 } 
{ Id = 6, Rank = 2, ExpectedRank = 2 } 
{ Id = 4, Rank = 3, ExpectedRank = 3 } 
{ Id = 3, Rank = 4, ExpectedRank = 4 } 
{ Id = 5, Rank = 4, ExpectedRank = 4 } 
{ Id = 1, Rank = 6, ExpectedRank = 6 } 
Verwandte Themen