简体   繁体   中英

Need help on this Linq GroupBy query

I am producing a report which will display daily usage over time.

I have the activity and the days coming through, however I would love some direction on how to achieve the following:

  • Day's grouped (so a single entry of 12/02/2018 should exist)
  • An Activity column summing entries for the day (eg. 35 for 12/02/2018)
  • A new column representing RecordCount (which is the amount of entries found per day, Eg. 12/02/2018 would display 2.)

What I have so far

// Engagement - Daily activity over time
PageStatistics.Where(x => x.Status == 1)
    .GroupBy(x => new { Day = x.CreatedAt.Date, x.AppID })
    .Select(x => new { Day = x.Key.Day, Activity = x.Count() })
    .OrderByDescending(x => x.Day)
    .ToList()
    .Select(x => new { Day = x.Day.ToString("dd/MM/yyyy"), Activity = x.Activity })

Thanks a lot.

Update

I am looking for Day, Activity(Total Count across all AppIDs) and RecordCount(Distinct AppID entries).

在此处输入图片说明

It seems to me you are already doing what you desire.

Given

public class Page
{
   public DateTime CreatedAt { get; set; }
   public int Status { get; set; }
   public int AppID { get; set; }
}

Group by CreatedAt and AppId

var result = pageStatistics.Where(x => x.Status == 1)
           .GroupBy(
              x => new
                 {
                    Day = x.CreatedAt.Date,
                    x.AppID
                 })
           .OrderByDescending(x => x.Key.Day)
           .Select(
              x => new
                 {
                    Day = x.Key.Day.ToString("dd/MM/yyyy"),
                    AppID = x.Key.AppID,
                    RecordCount = x.Count()
                 })
           .ToList();

Ie you are getting a list of all app activity on different Days

Note : i just put AppID = x.Key.AppID , to show you your groups


However, if you want group by CreatedAt (agnostic of AppId )

var result = pageStatistics.Where(x => x.Status == 1)
           .GroupBy(x => x.CreatedAt.Date)
           .OrderByDescending(x => x.Key.Date)
           .Select(
              x => new
                 {
                    Day = x.Key.Date.ToString("dd/MM/yyyy"),
                    RecordCount = x.Count()
                 })
           .ToList();

Update

These are the Driods you are looking for

var result = pageStatistics.Where(x => x.Status == 1)
              .GroupBy(
                    x => new
                       {
                          CreatedAt = x.CreatedAt.Date,
                          x.AppID
                       })
              .OrderByDescending(x => x.Key.CreatedAt)
              .Select(
                    x => new
                       {
                          x.Key.CreatedAt,
                          Activity = x.Count()
                       })
              .GroupBy(x => x.CreatedAt)
              .Select(
                    x => new
                    {
                       Day = x.Key.ToString("dd/MM/yyyy"),
                       Activity = x.Sum(y => y.Activity),
                       RecordCount = x.Count()
                    })
              .ToList();

In my understanding following shall suffice:

PageStatistics.Where(x => x.Status == 1)
    .GroupBy(x => new { Day = x.CreatedAt.Date })
    .Select(x => new { Date = x.Key.Date.ToString("dd/MM/yyyy"), 
                       Activity = x.Sum(y => y.AppID), 
                       Record = x.Count()});

Reviewing the questions, I have created the following Linqpad code, which produce the result as expected. I haven't appended OrderBy or extra Select , you can massage the data on need basis. Point remains since AppId is required for Sum and Count calculations, so we don't use it in the Grouping logic and use the value projection for the Sum (activity) and Record (Count) values. Also note, in the Select statement projection is a IGrouping collection, which can be further processed using Linq Select , SelectMany

Code

void Main()
{
    List<Page> PageStatistics = new List<UserQuery.Page>();

    PageStatistics.Add(new Page(new DateTime(2018,02,12),3));
    PageStatistics.Add(new Page(new DateTime(2018,02,12),32));
    PageStatistics.Add(new Page(new DateTime(2018,02,11),20));
    PageStatistics.Add(new Page(new DateTime(2018,02,11),44));
    PageStatistics.Add(new Page(new DateTime(2018,02,11),20));
    PageStatistics.Add(new Page(new DateTime(2018,02,11),2));
    PageStatistics.Add(new Page(new DateTime(2018,02,11),1));
    PageStatistics.Add(new Page(new DateTime(2018,02,10),22));
    PageStatistics.Add(new Page(new DateTime(2018,02,10),2));
    PageStatistics.Add(new Page(new DateTime(2018,02,10),20));
    PageStatistics.Add(new Page(new DateTime(2018,02,10),10));


    var result  = 
    PageStatistics.Where(x => x.Status == 1)
    .GroupBy(x => new { Day = x.CreatedAt.Date })
    .Select(x => new { Date = x.Key.Date.ToString("dd/MM/yyyy"), 
                       Activity = x.Sum(y => y.AppID), 
                       Record = x.Count()});

    result.Dump();
}

public class Page
{
    public DateTime CreatedAt { get; set; }
    public int Status { get; set; }
    public int AppID { get; set; }

    public Page(DateTime c, int a)
    {
        CreatedAt = c;
        AppID = a;  
        Status = 1;
    }
}

Result:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM