【问题标题】:How to SUM up results by column value in db query result如何在数据库查询结果中按列值求和结果
【发布时间】:2013-01-14 02:01:46
【问题描述】:

我的数据库有一个销售表,其中包含如下条目:

_____________________________________
| id |  title_id   |       qty      |
-------------------------------------
| 0  |  6          |        10      |
-------------------------------------
| 1  | 5           |        5       |
-------------------------------------
| 2  |  6          |        2       |
-------------------------------------

Title_id 是指向 Titles 表的外键,如下:

_____________________________________
| id |  title_id   |       title    |
-------------------------------------
| 0  |  5          |       Soda     |
-------------------------------------
| 1  |  6          |      Coffee    |
-------------------------------------

我想找到销量最高的 5 个产品,这意味着我需要计算每个产品在销售表中输入的所有产品的数量值,然后按数量按降序排列结果并将选择限制为 5。

但是,我是 C# ASP.NET 的新手,并且对 SQL 有点陌生。我不知道如何用 LINQ 做到这一点。 到目前为止,这是我的代码:

        var getIds = (from sale in db.sales
                      join tit in db.titles on sale.title_id equals tit.title_id
                      group sale by sale.qty into result
                      orderby result.Sum(i => i.qty) descending
                      select new Publication 
                      { 
                        PubID = sales.title_id, Title = tit.title
                      }
                      ).Take(5);

【问题讨论】:

  • 我建议您获取LINQPad - 有一个免费版本,非常适合测试这样的查询。

标签: c# asp.net sql linq


【解决方案1】:

假设您有一个导航属性Sale.Title,应该这样做:

var tops = 
  db.Sales
    .GroupBy( o => o.Title )
    .Select( o => new { Title = o.Key, Sum = o.Sum( x => x.Quantity ) } )
    .OrderByDescending( o => o.Sum )
    .Take( 5 )
    .ToList();

tops 是一个具有两个属性的匿名类型列表:Title 对象和数量之和。


然后你可以得到这样的值:

foreach( var top in tops )
{
  int titleId = top.Title.title_id;
  string title = top.Title.title;
  int sumOfQuantities = top.Sum;
  ...

如果你只想要顶部的Title 对象,可以这样选择它们:

List<Title> topTitles = tops.Select( o => o.Title ).ToList();

【讨论】:

  • 我如何添加加入到这个中你能帮我举出我写的例子吗?
  • @kellax 如果您使用的是 EF,则几乎不需要使用 Join。您能否编辑您的问题并添加 SaleTitle 类定义以便我们可以看到导航属性?
  • 问题是我的新出版物对象中不需要总和,我需要标题和 title_id。我只需要通过总结销售数量来订购它们
【解决方案2】:
var result= (from p in sales
              let k = new
              {
                  Name = p.Name
              }
              group p by k into t
              orderby Name descending
              select new
              {
                  Name = t.Name,
                  Qty = t.Sum(p => p.Qty)
              }).Take(5);

【讨论】:

  • OP 想要“销量最高”,此查询按名称排序,而不是按销量排序。
  • 发布了修改后的解决方案
【解决方案3】:

如果 Sales 表中的条目每件超过一个(即:在您的示例中,您有 'Soda' 10 + 'Soda' 2,那么您需要 GroupBy(),使用名称作为键(或如果它在另一个表中,则它是相关的 id),但不是数量。

var topSales = db.sales.GroupBy(x => x.title)
                       .Select(g => new 
                                    { 
                                       Title = g.Key, 
                                       Qty = g.Sum(x => x.qty)
                                    })
                       .OrderByDescending(x => x.Qty)
                       .Select(x => new Publication 
                                    { 
                                       PubID = x.Title.title_id, 
                                       Title = x.Title.title1
                                    })
                       .Take(5)
                       .ToList();

请注意,假设您在 sales.title_id -> title.id 之间有一个外键,并且您使用的是 LINQ to SQL,我省略了 join 语句。另请注意,我已经避免使用查询语法来支持链式方法语法,我认为在这个用例中很清楚(尽管并不总是如此,即:交叉连接)。

此外,SQL 和 LINQ 有一些相似之处,但不要让子句/方法的名称欺骗您,LINQ 不是 SQL,恕我直言,Microsoft 只是试图通过使其看起来相似来使人们感到舒适;)

编辑:固定 GroupBy()

【讨论】:

  • 您是否有将 TITLE 与 SALE 关联起来的外键?
  • 是 title_id 存在于titles 表和sales 表中。在销售表中设置为外键。
  • 我的错。我是用心写的。现在呢? .title 当然不存在。 g 包含分组项目的每个列表,虽然 .title 在同一个列表的每个元素中都是相同的,但编译器不知道;)
【解决方案4】:
var result= (from p in sales
              let k = new
              {
                  Name = p.Name
              }
              group p by k into t
              select new
              {
                  Name = t.Name,
                  Qty = t.Sum(p => p.Qty)
              }).OrderByDescending(i => i.Qty).Take(5);

【讨论】:

    【解决方案5】:

    您需要查看 GroupBy;这会给你你需要的东西

    http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

    【讨论】:

    • 我尝试了他们的例子,但并没有真正帮助我,我仍然卡住了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    • 2020-01-20
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多