【问题标题】:order by and project distinct objects排序和投影不同的对象
【发布时间】:2012-02-09 01:18:27
【问题描述】:

我有这样的数据:

 Id  |  Customer  |  CartTotal
-------------------------------
 1   |      a     |     100 
 2   |      a     |     50
 3   |      b     |     110
 4   |      b     |     128

我需要通过CartTotal(降序)订购并返回不同的客户 所以我的结果集中应该有这个:

 Id  |  Customer  |  CartTotal
-------------------------------
  4  |      b     |     128
  1  |      a     |     100

我认为我需要进行排序和投影。我正在使用强类型的IList<> 数据源。我是 LINQ 的新手。任何帮助将不胜感激。

【问题讨论】:

  • 我不明白您使用什么标准为 b 选择 CartTotal 的值 128 和为 a 选择 CartTotal 的值 100。每个都定义了两个单独的值,应该使用哪个?
  • @KirkWoll 如果我猜的话,我会说使用max :)
  • 你为什么选择 ID 1 和 4 而不是 2 和 3 ?您是否正在寻找具有最大 CartTotal 值的行?
  • 请不要在您的标题前加上“.net Linq:”之类的前缀。这就是标签的用途。
  • 是的,我需要每个客户的最大购物总价值@ThomasLevesque

标签: c# .net linq sql-order-by projection


【解决方案1】:

以下内容应该可以满足您的需求:

var filteredPurchases = purchases.OrderByDescending(p => p.CartTotal)
    .GroupBy(p => p.Customer)
    .Select(g => g.First());

它将以每个Customer 的最大CartTotal 返回购买,从而提供所需的结果。

【讨论】:

    【解决方案2】:

    到目前为止的答案虽然正确,但效率明显低于所需的,因为它们 1)在分组之前进行排序,并且 2)首先只需要最大的元素。先排序后得到解决方案O(n*log(n))

    考虑到数字 1,我们可以做到以下几点:

    var query = purchases
        .GroupBy(p => p.Customer)
        .Select(g => g.OrderByDescending(p => p.CartTotal).First());
    

    这为我们提供了类似O(n + n * log(n/c) 的解决方案,其中 c 是客户数量。假设每个客户的订单大致不变,则为O(n)

    现在,我们可以做得更好,只需找到每个客户的最大元素并一次性选择它。不幸的是,Linq 中的 Max 运算符使这比应有的更加痛苦。如果你拉下MoreLinq,你可以这样做:

    var query = purchases
        .GroupBy(p => p.Customer)
        .Select(g => g.MaxBy(p => p.CartTotal));
    

    此解决方案始终为O(n),无论购买分配给客户如何。我还希望它是迄今为止在大型数据集上最快的。

    【讨论】:

      【解决方案3】:

      这是一个查询表达式版本:

      var query = from cart in carts
                  orderby cart.CartTotal descending
                  group cart by cart.Customer into custCarts
                  select custCarts.First();
      

      【讨论】:

      • 感谢分享查询表达式语法@AndrewCooper
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-27
      • 2019-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多