2

I have a database table of events. Each event has a category and a date/time.

(actually events have sub-categories which are contained in categories and various other properties, left out in this simplified example)

I want to generate a list with an entry for each hour and category, listing the number of events and their percentage.

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%
...

I am having trouble calculating the percentage efficiently. Here is what I have so far:

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
  }

How can I get the value for [total number of events for this hour], ideally in an elegant and efficient way?

4

2 回答 2

4

这是我想出的:

        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
于 2012-04-10T15:34:36.573 回答
1

您必须先按天分组,然后从那里选择总数……例如:

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()
  }

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

于 2012-04-10T15:31:20.767 回答