【问题标题】:Linq-To-SQL GroupBy: How to calculate percentage columnLinq-To-SQL GroupBy:如何计算百分比列
【发布时间】:2012-04-10 15:18:13
【问题描述】:

我有一个事件数据库表。每个事件都有一个类别和一个日期/时间。

(实际上事件具有包含在类别和各种其他属性中的子类别,在此简化示例中省略了)

我想生成一个列表,其中包含每个小时和类别的条目,列出事件的数量及其百分比。

date            | category | number of events | percentage
----------------------------------------------------------
2012-01-01 1:00 | cat-1    | 10               | 50%
2012-01-01 1:00 | cat-2    | 10               | 50%
2012-01-01 2:00 | cat-1    | 1                | 10%
2012-01-01 2:00 | cat-2    | 9                | 90%
2012-01-01 3:00 | cat-1    | 3                | 100%
...

我无法有效地计算百分比。 这是我目前所拥有的:

var results = datacontext.events.
  groupBy(e=>new   
  {  // group by category and hour
     category = e.category,
     datetime = new DateTime (
       e.datetime.Year, e.datetime.Month, e.datetime.Day, 
       e.datetime.Hour, 0, 0 ) 
     // use date+hour for grouping, ignore minutes/seconds
  }).
  select(group => new 
  {
     category = group.Key.category,
     datetime = group.Key.datetime,
     numberOfEvents = group.count(),
     percentage = group.count() / ["total number of events for this hour"] * 100.0
  }

我怎样才能获得 [这一小时的事件总数] 的值,理想情况下以一种优雅而有效的方式?

【问题讨论】:

    标签: c# linq linq-to-sql group-by


    【解决方案1】:

    这是我想出的:

            var results = from events in datacontext.events
                          let date = new DateTime(
                                 events.datetime.Year, events.datetime.Month, events.datetime.Day,
                                 events.datetime.Hour, 0, 0)
                          let total = datacontext.events.Where(x => x.datetime.Date == date.Date && x.datetime.Hour == date.Hour).Count()
                          group events by new
                          {  // group by category and hour
                              category = events.category,
                              datetime = date,
                              total = total
                          } into e
                          select new
                          {
                              category = e.Key.category,
                              day = e.Key.datetime.Day,
                              numberOfEvents = e.Count(),
                              percentage = (float)e.Count() / (float)e.Key.total
                          };
    

    两个焦点:

    1. 使用浮点数表示百分比
    2. 使用let 计算Date 的总数

    【讨论】:

    • 谢谢!我一般不使用query snytax,但是意思很清楚。
    • 我遇到了类似 OP 的问题,我的百分比始终为 0。当我将计数和总数转换为浮点数时,我终于得到了所需的百分比。非常感谢。 :)
    【解决方案2】:

    您必须先按天分组,然后从那里选择总计...类似于:

    var resultsPerDay = datacontext.events.groupBy(e=>new {
        datetime = new DateTime (
            e.datetime.Year, e.datetime.Month, e.datetime.Day, 
            e.datetime.Hour, 0, 0 )
        }
    }).select(group=>new {
        datetime = group.Key.datetime,
        totalForADay = group.Key.count()
    });
    
    
    
    var results = datacontext.events.
      groupBy(e=>new   
      {  // group by category and hour
         category = e.category,
         datetime = new DateTime (
           e.datetime.Year, e.datetime.Month, e.datetime.Day, 
           e.datetime.Hour, 0, 0 ) 
         // use date+hour for grouping, ignore minutes/seconds
      }).
      select(group => new 
      {
         category = group.Key.category,
         datetime = group.Key.datetime,
         numberOfEvents = group.count(),
         percentage = 100 * group.count() / resultsPerDay.where(p=>p.datetime == group.Key.datetime).select(p=>p.totalForADay).SingleOrDefault()
      }
    

    但不确定这是否是最有效的方法。另外,由于我没有通过编译器将其放入,因此不确定语法是否良好,但您明白了。

    【讨论】:

    • 谢谢,这有帮助。我想知道,groupBy 的第一个查询是否比以后使用percentage = 100.0 * group.count() / events.where(e=>e.datetime.Date==group.Key.datetime.Date && e.datetime.Hour==group.Key.datetime.Hour) 更有效?
    • 我不确定您是否会注意到任何不同。
    猜你喜欢
    • 1970-01-01
    • 2022-06-13
    • 2019-01-26
    • 2023-02-01
    • 1970-01-01
    • 2015-06-11
    • 2018-03-24
    • 2020-10-11
    • 1970-01-01
    相关资源
    最近更新 更多