每列第一列的列的前5位和另一列的前5位

时间:2016-10-21 10:23:42

标签: c# linq

我有以下格式的大量数据..

var data1 = new[] { 
    new { Product = "Product 1", Year = 2009, Sales = 1212 },
    new { Product = "Product 2", Year = 2009, Sales = 522 },
    new { Product = "Product 1", Year = 2010, Sales = 1337 },
    new { Product = "Product 2", Year = 2011, Sales = 711 },
    new { Product = "Product 2", Year = 2012, Sales = 2245 },
    new { Product = "Product 3", Year = 2012, Sales = 1000 }
};

如果我想获得最大销量的前20行,我可以做以下事情。

data1.OrderByDescending(o=>o.Sales).Take(20);

但我想做的是获得前5名产品和(对于那些产品)前5年以及他们的销售。

因此,输出将如下所示:

var outputdata = new[] {  
    new { Product = "Product 1", Year = 2012, Sales = 2245 },
    new { Product = "Product 1", Year = 2010, Sales = 1337 },
    new { Product = "Product 1", Year = 2009, Sales = 1212 },
    new { Product = "Product 1", Year = 2011, Sales = 711 },
    new { Product = "Product 1", Year = 2013, Sales = 522 },  
    new { Product = "Product 2", Year = 2012, Sales = 1000 }
};
对于sql,

This可能是一个类似的问题。但遗憾的是无法理解如何转换为linq。

3 个答案:

答案 0 :(得分:1)

好的,如果我理解正确:首先按product分组,这样您就可以按产品的总sales订购。 然后你只能拿走你想要的金额。使用SelectMany展开论坛:

var data = new[] {
          new { Product = "Product 1", Year = 2009, Sales = 1212 },
          new { Product = "Product 2", Year = 2009, Sales = 522 },
          new { Product = "Product 1", Year = 2010, Sales = 1337 },
          new { Product = "Product 2", Year = 2011, Sales = 711 },
          new { Product = "Product 2", Year = 2012, Sales = 2245 },
          new { Product = "Product 3", Year = 2012, Sales = 1000 }
      };
int numberOfProducts = 2;
int numberOfYearsForEachProduct = 3;

var result = data.GroupBy(x => x.Product)
    .OrderByDescending(x => x.Sum(y => y.Sales)) //Order products by their total sum of `Sales`
    .Take(numberOfProducts )
    .SelectMany(x => x.OrderByDescending(y => y.Sales).Take(numberOfYearsForEachProduct)) // Take only the N top years for each product
    .ToList();

我在Take中使用了较小的数字,因此我可以看到它正确地执行了

答案 1 :(得分:1)

首先,您应该获得最畅销的20种产品

var top20Products = data1
    .GroupBy(x => x.Product)
    .OrderByDescending(group => group.Sum(x => x.Sales))
    .Select(group => group.Key)
    .Take(20);

然后选择最畅销的前五年

var top5yearsOfTop20products = top20Products
    .SelectMany(product => data1
        .Where(x => x.Product == product)
        .OrderByDescending(x => x.Sales)
        .Take(5));

答案 2 :(得分:0)

如果我找到你,你想获得前5名产品的前20名。

var ord = data1.OrderByDescending(o => o.Sales)
               .Select(o => o.Product)
               .Distinct().Take(5);//Get top 5 products by their sales

var salesForTopProducts = data1.OrderByDescending(o => o.Sales)
                               .Where(o => ord.Contains(o.Product))
                               .Take(20);//Get top 20 sales for top 5 products