简体   繁体   English

如何对多列进行分组并计数?

[英]How can I group with multiple columns and count?

Firstly, I just cannot explain my question in the title properly, but I don't think its a duplicate.首先,我无法在标题中正确解释我的问题,但我认为它不是重复的。 I have a List of model which id like to group by multiple fields, then count them into new field, and keep all the other field in the result.我有一个 model 列表,它 id 喜欢按多个字段分组,然后将它们计入新字段,并将所有其他字段保留在结果中。 I am sorry for the bad explanation, I've been researching how to do this for hours and I just cannot figure it out.. I would like to get from this:对于错误的解释,我很抱歉,我已经研究了几个小时如何做到这一点,但我无法弄清楚..我想从中得到:

SaleID销售编号 Name名称 Product产品 Address地址 Phone电话 PrintType打印类型
112 112 Joe Apple苹果 New street 12新街12 11223344 11223344 PrintType1打印类型 1
112 112 Joe Apple苹果 New street 12新街12 11223344 11223344 PrintType2打印类型2
112 112 Joe Apple苹果 New street 12新街12 11223344 11223344 PrintType2打印类型2
112 112 Joe Apple苹果 New street 12新街12 11223344 11223344 PrintType2打印类型2
112 112 Joe Apple苹果 New street 12新街12 11223344 11223344 PrintType3打印类型3
113 113 Joe Kiwi猕猴桃 New street 12新街12 11223344 11223344 PrintType3打印类型3
114 114 Jane Orange橙子 New street 19新街19号 72754722 72754722 PrintType1打印类型 1
115 115 John约翰 Orange橙子 New street 11新街11号 99236527 99236527 PrintType2打印类型2
115 115 John约翰 Orange橙子 New street 11新街11号 99236527 99236527 PrintType2打印类型2

Grouped by SaleID and PrintType into Something like this:按 SaleID 和 PrintType 分组,如下所示:

SaleID销售编号 Name名称 Product产品 Address地址 Phone电话 NoOfPrintType1 NoOfPrintType1 NoOfPrintType2 NoOfPrintType2 NoOfPrintType3 NoOfPrintType3
112 112 Joe Apple苹果 New street 12新街12 11223344 11223344 1 1个 3 3个 1 1个
113 113 Joe Kiwi猕猴桃 New street 12新街12 11223344 11223344 0 0 0 0 1 1个
114 114 Jane Orange橙子 New street 19新街19号 72754722 72754722 1 1个 0 0 0 0
115 115 John约翰 Orange橙子 New street 11新街11号 99236527 99236527 0 0 2 2个 0 0

Preferably id like to use LINQ, but id be good with SQL too, id just like to avoid using a for loop if possible.最好 id 喜欢使用 LINQ,但 id 也可以使用 SQL,id 只是想尽可能避免使用 for 循环。 Edit.: There are a set number of printtypes so it wouldn't need to be dynamic.编辑:有一定数量的打印类型,因此它不需要是动态的。

In order to aggregate the data for a set number of PrintTypes, you can group by SaleId as the additional data like address, phone and product are the same for a SaleId (based on your sample data).为了聚合一组 PrintTypes 的数据,您可以按 SaleId 分组,因为地址、电话和产品等附加数据对于 SaleId 是相同的(基于您的示例数据)。

var aggregated = from x in GenerateSales() 
    group x by x.SaleId into g // Assume that SaleId is the key that you want to group by
    select new Aggregate() 
    { 
        SaleId = g.Key, 
        // Additional data that are the same for all rows with the same SaleId
        Name = g.First().Name, 
        Product = g.First().Product, 
        Address = g.First().Address, 
        Phone = g.First().Phone, 
        // Calculate counts of Print Types
        NoOfPrintType1 = g.Where(x => x.PrintType == "PrintType1").Count(),
        NoOfPrintType2 = g.Where(x => x.PrintType == "PrintType2").Count(),
        NoOfPrintType3 = g.Where(x => x.PrintType == "PrintType3").Count(),
    };

The Linq statement first groups by SaleId and then creates an object for each SaleId, that comprises Linq 语句首先按 SaleId 分组,然后为每个 SaleId 创建一个 object,它包括

  • the SaleId销售编号
  • the additional data like address, phone...地址,电话等附加数据...
  • the count for each known PrintType (calculated by filtering the items of the group and then counting the rows)每个已知 PrintType 的计数(通过过滤组的项目然后计算行数来计算)

Below you can find a sample that generates test data and outputs the result.您可以在下面找到生成测试数据并输出结果的示例。

Result结果

112 | Joe | Apple | New street 12 | 11223344 | 1 | 3 | 1
113 | Joe | Kiwi | New street 12 | 11223344 | 0 | 0 | 1
114 | Jane | Orange | New street 19 | 72754722 | 1 | 0 | 0
115 | John | Orange | New street 11 | 99236527 | 0 | 2 | 0

Sample code示例代码

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqTest
{
    class Sale 
    {
        public string SaleId { get; set; }
        public string Name { get; set; }
        public string Product { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string PrintType { get; set; }
    }

    class Aggregate 
    {
        public string SaleId { get; set; }
        public string Name { get; set; }
        public string Product { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public int NoOfPrintType1 { get; set; }
        public int NoOfPrintType2 { get; set; }
        public int NoOfPrintType3 { get; set; }

        public override string ToString() 
        {
            return $"{SaleId} | {Name} | {Product} | {Address} | {Phone} | {NoOfPrintType1} | {NoOfPrintType2} | {NoOfPrintType3}";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var aggregated = from x in GenerateSales() 
                group x by x.SaleId into g // Assume that SaleId is the key that you want to group by
                select new Aggregate() 
                { 
                    SaleId = g.Key, 
                    // Additional data that are the same for all rows with the same SaleId
                    Name = g.First().Name, 
                    Product = g.First().Product, 
                    Address = g.First().Address, 
                    Phone = g.First().Phone, 
                    // Calculate counts of Print Types
                    NoOfPrintType1 = g.Where(x => x.PrintType == "PrintType1").Count(),
                    NoOfPrintType2 = g.Where(x => x.PrintType == "PrintType2").Count(),
                    NoOfPrintType3 = g.Where(x => x.PrintType == "PrintType3").Count(),
                };
            foreach(var a in aggregated)
            {
                Console.WriteLine(a.ToString());
            }
        }

        static IEnumerable<Sale> GenerateSales()
        {
            yield return new Sale() { SaleId = "112", Name = "Joe", Product = "Apple", Address = "New street 12", Phone = "11223344", PrintType = "PrintType1" };
            yield return new Sale() { SaleId = "112", Name = "Joe", Product = "Apple", Address = "New street 12", Phone = "11223344", PrintType = "PrintType2" };
            yield return new Sale() { SaleId = "112", Name = "Joe", Product = "Apple", Address = "New street 12", Phone = "11223344", PrintType = "PrintType2" };
            yield return new Sale() { SaleId = "112", Name = "Joe", Product = "Apple", Address = "New street 12", Phone = "11223344", PrintType = "PrintType2" };
            yield return new Sale() { SaleId = "112", Name = "Joe", Product = "Apple", Address = "New street 12", Phone = "11223344", PrintType = "PrintType3" };
            yield return new Sale() { SaleId = "113", Name = "Joe", Product = "Kiwi", Address = "New street 12", Phone = "11223344", PrintType = "PrintType3" };
            yield return new Sale() { SaleId = "114", Name = "Jane", Product = "Orange", Address = "New street 19", Phone = "72754722", PrintType = "PrintType1" };
            yield return new Sale() { SaleId = "115", Name = "John", Product = "Orange", Address = "New street 11", Phone = "99236527", PrintType = "PrintType2" };
            yield return new Sale() { SaleId = "115", Name = "John", Product = "Orange", Address = "New street 11", Phone = "99236527", PrintType = "PrintType2" };
        }
    }
}

you can use this SQL query你可以使用这个 SQL 查询

with x as (
   SELECT  [SaleID],[Name],[Product],[Address],[Phone],[PrintType]
          ,case when [PrintType]='PrintType1' then count(*) else 0 end NoOfPrintType1
          ,case when [PrintType]='PrintType2' then count(*) else 0 end NoOfPrintType2
          ,case when [PrintType]='PrintType3' then count(*) else 0 end NoOfPrintType3
      FROM [Table_1]
      group by [SaleID] ,[Name],[Product],[Address],[Phone] ,[PrintType])
    
    select [SaleID],[Name],[Product],[Address],[Phone]
          ,sum(NoOfPrintType1)NoOfPrintType1
          ,sum(NoOfPrintType2)NoOfPrintType2
          ,sum(NoOfPrintType3)NoOfPrintType3 from x
   group by [SaleID]
          ,[Name],[Product],[Address],[Phone]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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