【问题标题】:Group linq results by value and group null or invalid values and do counts按值对 linq 结果进行分组,并对空值或无效值进行分组并进行计数
【发布时间】:2019-07-29 03:51:37
【问题描述】:

这是this question 的后续问题。我现在想对分组进行一些计数。

原始查询:排除无效邮政编码做了以下操作:

  List<DataSourceRecord> md = (from rst in QBModel.ResultsTable
        where (!String.IsNullOrWhiteSpace(rst.CallerZipCode) && rst.CallerZipCode.Length > 2)
        group rst by rst.CallerZipCode.Substring(0, 3) into newGroup
        orderby newGroup.Key
        select new DataSourceRecord()
        {
          State = newGroup.Select(i => i.CallerState).FirstOrDefault(),
          ZipCode = newGroup.Where(z => z.CallerZipCode.StartsWith(newGroup.Key)).Select(x => x.CallerZipCode.Substring(0, 3)).FirstOrDefault(),
          Calls = newGroup.Where(x => x.CallerZipCode.StartsWith(newGroup.Key) && x.CALL_ID > 0).Distinct().GroupBy(g => new { g.CallerZipCode, g.CTR_ID, g.CALL_ID }).Count(),
          Exposures = newGroup.Where(x => x.CallerZipCode.StartsWith(newGroup.Key) && x.CALL_ID > 0 && x.ExposureCount > 0).Distinct().GroupBy(x => new { x.CallerState, x.CTR_ID, x.CALL_ID }).Count()
        }).ToList();

新示例 1: 现在使用新分组,包括无效的邮政编码分组:

List<DataSourceRecord> newset = (from rst in QBModel.ResultsTable
  group rst by GetGroupRepresentation(rst.CallerZipCode) into newGroup
  select new DataSourceRecord()
  {
    State = newGroup.Select(i => i.CallerState).FirstOrDefault(),
    ZipCode = newGroup.Key,
    Calls = ???
    Exposures = ???
  }).ToList();

分组方式:

private string GetGroupRepresentation(string zipCode)
{
    if (string.IsNullOrEmpty(zipCode) || zipCode.Length < 3)
        return "<null>";
    return zipCode.Substring(0,3);
}

新示例 2: 我认为我还可以执行以下操作:

List<DataSourceRecord> newset = (from rst in QBModel.ResultsTable
  group rst by rst.CallerZipCode == null || rst.CallerZipCode.Trim().Length < 3 ? "<null>" : rst.CallerZipCode.Substring(0, 3) into newGroup
  select new DataSourceRecord()
  {
    State = newGroup.Select(i => i.CallerState).FirstOrDefault(),
    ZipCode = newGroup.Key,
    Calls = ???
    Exposures = ???
  }).ToList();

我试图找出我需要在原始查询中更改新查询中分组的“呼叫”和“暴露”这两个计数的内容。实现这一点需要如何以及需要什么?

[编辑]同一问题的扩展:

如何使用两个或多个属性配置分组。在下面

List<DataSourceRecord> 
    newset = (from rst in QBModel.ResultsTable
              group rst by GetGroupRepresentation(rst.CallerZipCode, rst.CallerState) into newGroup
              select new MapDataSourceRecord()
              {
                State = ToTitleCase(newGroup.Select(i => i.CallerState).FirstOrDefault()),
                StateFIPS = FipsForStateCD(newGroup.Select(i => i.CallerStateCD).FirstOrDefault()),
                ZipCode = newGroup.Key[0],
                Calls = newGroup.Where(x => x.CALL_ID > 0).Distinct().Count(),
                Exposures = newGroup.Where(x => x.CALL_ID > 0 && x.EXPO_ID > 0).Distinct().Count(),
                InfoRequests = newGroup.Where(x => x.CALL_ID > 0 && x.INFO_ID > 0).Distinct().Count(),
                Population = GetZipCode3Population(newGroup.Key[0])
              }).ToList();

方法:

    private string[] GetGroupRepresentation(string ZipCode, string State)
    {
      string ZipResult;
      string StateResult;
      if (string.IsNullOrEmpty(ZipCode) || ZipCode.Length < 3)
        ZipResult = "<null>";
      else
        ZipResult = ZipCode.Substring(0, 3);

      if (string.IsNullOrEmpty(State))
        StateResult = "<null>";
      else
        StateResult = State;

      return  new string[]{ ZipResult, State };
    }

【问题讨论】:

  • 是的,“新示例 2”做同样的事情,但是,我认为更难理解发生了什么。

标签: c# linq group-by iequalitycomparer


【解决方案1】:

首先关于电话:

Calls = newGroup.Where(x => x.CallerZipCode.StartsWith(newGroup.Key) && x.CALL_ID > 0).Distinct().GroupBy(g => new { g.CallerZipCode, g.CTR_ID, g.CALL_ID }).Count(),

据我了解,您希望该组具有 CALL_ID &gt; 0 的不同呼叫次数。我不明白您为什么要使用邮政编码、CTR_ID 和 CALL_ID 创建一个新组。 如果我理解正确的话,Exposures 非常相似。

List<DataSourceRecord> newset = (from rst in QBModel.ResultsTable
  group rst by GetGroupRepresentation(rst.CallerZipCode) into newGroup
  select new DataSourceRecord()
  {
    State = newGroup.Select(i => i.CallerState).FirstOrDefault(),
    ZipCode = newGroup.Key,
    Calls = newGroup.Where(x => x.CALL_ID > 0).Select(x => x.CALL_ID).Distinct().Count(),
    Exposures = newGroup.Where(x => x.CALL_ID > 0 && x.ExposureCount > 0).Distinct().Count()
  }).ToList();

如果您真的想对呼叫/曝光进行分组,这意味着您想要计算(CTR_ID 和 CALL_ID / CallerState、CTR_ID 和 CALL_ID)的唯一组合,您当然可以这样做。

【讨论】:

  • 我不得不承认现有的代码让我很困惑。我只是想更新它。是的,通话和曝光非常相似,让我感到困惑的是第二组
  • 好吧,在这种情况下,您应该找出您的要求是什么。可悲的是,这里没有人可以帮助您。您需要找出“您需要做什么”,然后有人可能会帮助您解决“如何做到这一点”。
  • 好的,我明白你所说的需求。一个额外的问题,如果我想按一个额外的属性 rst.CallerState 或多个属性分组怎么办。我会发送 GetGroupRepresentation() 参数并返回一个值数组。我在问题的最后做了一个Edit 作为例子。
猜你喜欢
  • 1970-01-01
  • 2018-03-01
  • 2017-12-13
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 2011-05-26
  • 2018-01-12
相关资源
最近更新 更多