在每个商店国家部分中选择出生值最高的行

Posted

技术标签:

【中文标题】在每个商店国家部分中选择出生值最高的行【英文标题】:Pick line with the highest value of birth in every shop-country section 【发布时间】:2021-07-19 23:57:37 【问题描述】:

已经尝试了几个小时来解决问题,但我无法解决问题 这是我在pastebin 上使用的表格

var result = E
                .Join(A, a => a.ID, aa => aa.ID,
                    (EE, AA) => new AA.ID, AA.Birth, AA.Street, EE.Code, EE.Shop)
                .Join(D, d => d.Code, dd => dd.Code,
                    (AE, DD) => new AE.ID, AE.Birth, AE.Street, AE.Shop, DD.Code, DD.Price)
                .Join(B, b => b.Code, bb => bb.Code,
                    (AED, BB) => new AED.ID, AED.Birth, AED.Shop, AED.Price, BB.Country)
                .GroupBy(g => new
                
                    g.ID, g.Birth, g.Shop, g.Country
                )
                .Select(s => new
                
                    s.Key.ID, s.Key.Birth, 
                    ShopCont = s.Key.Shop + "-" + s.Key.Country, 
                    Total = s.Sum(ss => ss.Price)
                );

这就是结果的样子

 ID = 1, Birth = 1992, ShopCont = Gucci-Nigeria, Total = 64 
 ID = 2, Birth = 2001, ShopCont = Gucci-Russia, Total = 41 
 ID = 3, Birth = 1998, ShopCont = Gucci-Russia, Total = 123  // this should be removed
 ID = 3, Birth = 1998, ShopCont = Dior-Russia, Total = 32  
 ID = 4, Birth = 2003, ShopCont = Dior-USA, Total = 23 
 ID = 1, Birth = 1992, ShopCont = Adidas-USA, Total = 1290 
 ID = 1, Birth = 1992, ShopCont = Adidas-Germany, Total = 321 
 ID = 5, Birth = 2005, ShopCont = Dixi-Germany, Total = 4 
 ID = 5, Birth = 2005, ShopCont = Dixi-France, Total = 1890 
 ID = 4, Birth = 2003, ShopCont = Dixi-France, Total = 1695  // this should be removed 

我想看看这个

 ID = 1, Birth = 1992, ShopCont = Gucci-Nigeria, Total = 64 
 ID = 2, Birth = 2001, ShopCont = Gucci-Russia, Total = 41 
 ID = 3, Birth = 1998, ShopCont = Dior-Russia, Total = 32 
 ID = 4, Birth = 2003, ShopCont = Dior-USA, Total = 23 
 ID = 1, Birth = 1992, ShopCont = Adidas-USA, Total = 1290 
 ID = 1, Birth = 1992, ShopCont = Adidas-Germany, Total = 321 
 ID = 5, Birth = 2005, ShopCont = Dixi-Germany, Total = 4 
 ID = 5, Birth = 2005, ShopCont = Dixi-France, Total = 1890 

【问题讨论】:

为什么你认为应该删除这些行?它们不是重复的。他们是不同的年份。 是的,你是对的,但目的是在每个商店国家部分中选择出生价值最高的路线。这是书中的练习 执行 OrderByDescending(x => x.Total) 然后执行 GroupBy(x => x.ShopCont) 最后从每个组中选择第一个 .Select(x => x.First()) 【参考方案1】:

您可以尝试在查询的最后添加GroupBy + Select (SelectMany):

var result = E
   ...
  .Select(s => new 
     s.Key.ID, 
     s.Key.Birth, 
     ShopCont = s.Key.Shop + "-" + s.Key.Country, 
     Total    = s.Sum(ss => ss.Price)
   )
  .GroupBy(item => item.ShopCont) // we group by shop
  .Select(g => g                  // in each shop
     .OrderByDescending(item => item.Birth) // we take the latest
     .First());                             // item only   

我们在这里分组Birth,取唯一最新的。

编辑:如果我们可以有 duplicate Birth 我们可以 group 他们(我宁愿实现我自己的扩展方法,但是在解决书中的问题时通常是不允许的):

  ... 
  .Select(s => new 
          s.Key.ID,
          s.Key.Birth, // Let's declare it explicitly
          ShopCont = s.Key.Shop + "-" + s.Key.Country,
          Total = s.Sum(ss => ss.Price)
        )
  .GroupBy(item => item.ShopCont) // we group by shop
  .SelectMany(outer => outer
    .GroupBy(item => item.Birth)
    .OrderByDescending(inner => inner.Key)
    .First()); 

现在我们按Birth分组(我们想要一个组,因为它可以返回不止一条记录);用OrderByDescendingFirst 选择正确的组,我们最终在SelectMany 的帮助下将其展平

【讨论】:

[CS0411] 无法从用法中推断方法“Enumerable.SelectMany(IEnumerable, Func>)”的类型参数。尝试明确指定类型参数。 @invis:抱歉,您只需要整个组中的一项(最新一项);因为我们只有一个项目,所以没有什么可以展平,也不需要SelectMany(但Select 但是如果不是只有一个最高值,那么我们需要全部取走。我应该在这里做什么 那么,如果我们有两个或更多记录具有相同的ShopContBirth,我们必须保留它们全部?跨度>

以上是关于在每个商店国家部分中选择出生值最高的行的主要内容,如果未能解决你的问题,请参考以下文章

sql WHERE NOT选择不等于值的行。它忽略NULL值,因此在示例中,具有不是“USA”的国家/地区的行

如何编写 SQL 来选择具有每个组的最大值(值)的行?

sql - 使用聚合函数(最小值/最大值)作为选择语句的一部分

在UITableView ios的每个部分中选择一行?

Mysql按日期时间的日期部分分组,并为每个日期选择具有最大日期时间的行

如何按升序选择每个类别的最高价格的行?