title: LINQ Query to Group by Multiple and Order
body: <p>I have the following data structure:</p>
  
  <pre><code>public class Difference
  {
      public Difference() { }
      public Differential Type { get; set; }
      public int Magnitude { get; set; }
  }
  public enum Differential
  {
      low,
      middle,
      high
  }
  </code></pre>
  
  <p>I may have the following data:</p>
  
  <pre><code>Magnitude      Type
  4456           low
  4456           low
  4423           low
  4421           low
  1000           high
  1000           high
  1001           high
  1560           middle
  4456           low
  4421           low
  </code></pre>
  
  <p>Im trying to return a dataset that gives me the <strong>Count</strong> on the number identical maginitudes and their types <strong>BUT ONLY THE TOP IN EACH TYPE</strong> in descending order of count so for the above (in order)</p>
  
  <p><strong>Value:</strong> 4456  <strong>Type:</strong> Low  <strong>Count:</strong> 3</p>
  
  <p><strong>Value:</strong> 1000  <strong>Type:</strong> High  <strong>Count:</strong> 2</p>
  
  <p><strong>Value:</strong> 1560  <strong>Type:</strong> Middle  <strong>Count:</strong> 1</p>
  
  <p>Notice how 4421 at a count of 2 wasn't in there because 4456 had a larger count?</p>
  
  <p>i think i have got close but not quite there:</p>
  
  <pre><code>var query = (from value in differences
               group value by new {value.Magnitude, value.Type} into groupjoin
               select new
               {
                   Value = groupjoin.Key.Magnitude,
                   Type = groupjoin.Key.Type,
                   Count = groupjoin.Count()                                         
               })
              .OrderByDescending(v =&gt; v.Count)
              .ThenByDescending(v =&gt; v.Value).ThenByDescending(v =&gt; v.Type).ToList();
  </code></pre>
  
  <p>UPDATE</p>
  
  <p>Based on what was suggested below by Douglas ive managed to implement it with the following. Im not too concerned though if there are ties, i would like to return just the First() one (for each type) if possible. i can only do this by looping:</p>
  
  <pre><code>var query = (from value in differences
                                   /*where value.type == Differential.low*/
                                   group value by new {value.Magnitude, value.Type} into groupjoin
                                   select new
                                   {
                                       Value = groupjoin.Key.Magnitude,
                                       Type = groupjoin.Key.Type,
                                       Count = groupjoin.Count()                                         
                                   });
  
                      var query2 = query.Where(g1 =&gt; !query.Any(g2 =&gt;
                                      g2.Type == g1.Type &amp;&amp;
                                      g2.Count &gt; g1.Count));
  
                      int highest = 0;
                      int lowest = 0;
                      int middle = 0;
                      foreach (var item in query2)
                      {
                          if (item.Type == Differential.high &amp;&amp; item.Count &gt; highest) 
                          {
                              oresult.numberOfHighHits = item.Count;
                              oresult.highTimeMagnitude = item.Value;
                          }
                          if (item.Type == Differential.low &amp;&amp; item.Count &gt; lowest)
                          {
                              oresult.numberOfLowHits = item.Count;
                              oresult.lowTimeMagnitude = item.Value;
                          }
                          if (item.Type == Differential.middle &amp;&amp; item.Count &gt; middle)
                          {
                              oresult.numberOfMiddleHits = item.Count;
                              oresult.middleTimeMagnitude = item.Value;
                          }
                      }
  </code></pre>