如何在db查询结果中按列值汇总结果

本文关键字:结果 db 查询 | 更新日期: 2023-09-27 17:52:56

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

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

Title_id是指向标题表的外键,如下所示:

_____________________________________
| 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);

如何在db查询结果中按列值汇总结果

假设您有一个导航属性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();
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);

如果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();

注意,我省略了join语句,假设在sales之间有一个外键。Title_id ->标题。id,并且正在使用LINQ to SQL。还请注意,我已经避免使用查询语法,而支持链式方法语法,我认为在这个用例中它更清楚(尽管并不总是正确的,例如:交叉连接)。

同样,SQL和LINQ有一些相似之处,但不要让子句/方法的名字欺骗了你,LINQ不是SQL, IMHO,微软只是试图让人们舒服,让它看起来很像;)

EDIT: fixed GroupBy()

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);

您需要查看GroupBy;这将给你你所需要的

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