[英]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 ![]() |
Joe![]() |
Apple![]() |
New street 12![]() |
11223344 ![]() |
PrintType1![]() |
112 ![]() |
Joe![]() |
Apple![]() |
New street 12![]() |
11223344 ![]() |
PrintType2![]() |
112 ![]() |
Joe![]() |
Apple![]() |
New street 12![]() |
11223344 ![]() |
PrintType2![]() |
112 ![]() |
Joe![]() |
Apple![]() |
New street 12![]() |
11223344 ![]() |
PrintType2![]() |
112 ![]() |
Joe![]() |
Apple![]() |
New street 12![]() |
11223344 ![]() |
PrintType3![]() |
113 ![]() |
Joe![]() |
Kiwi![]() |
New street 12![]() |
11223344 ![]() |
PrintType3![]() |
114 ![]() |
Jane![]() |
Orange![]() |
New street 19![]() |
72754722 ![]() |
PrintType1![]() |
115 ![]() |
John![]() |
Orange![]() |
New street 11![]() |
99236527 ![]() |
PrintType2![]() |
115 ![]() |
John![]() |
Orange![]() |
New street 11![]() |
99236527 ![]() |
PrintType2![]() |
Grouped by SaleID and PrintType into Something like this:按 SaleID 和 PrintType 分组,如下所示:
SaleID![]() |
Name![]() |
Product![]() |
Address![]() |
Phone![]() |
NoOfPrintType1 ![]() |
NoOfPrintType2 ![]() |
NoOfPrintType3 ![]() |
---|---|---|---|---|---|---|---|
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 ![]() |
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,它包括
Below you can find a sample that generates test data and outputs the 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
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.