[英]How can I use LINQ to select columns from multiple tables with Count and Group By?
[英]How can I group with multiple columns and count?
首先,我无法在标题中正确解释我的问题,但我认为它不是重复的。 我有一个 model 列表,它 id 喜欢按多个字段分组,然后将它们计入新字段,并将所有其他字段保留在结果中。 对于错误的解释,我很抱歉,我已经研究了几个小时如何做到这一点,但我无法弄清楚..我想从中得到:
销售编号 | 名称 | 产品 | 地址 | 电话 | 打印类型 |
---|---|---|---|---|---|
112 | 乔 | 苹果 | 新街12 | 11223344 | 打印类型 1 |
112 | 乔 | 苹果 | 新街12 | 11223344 | 打印类型2 |
112 | 乔 | 苹果 | 新街12 | 11223344 | 打印类型2 |
112 | 乔 | 苹果 | 新街12 | 11223344 | 打印类型2 |
112 | 乔 | 苹果 | 新街12 | 11223344 | 打印类型3 |
113 | 乔 | 猕猴桃 | 新街12 | 11223344 | 打印类型3 |
114 | 简 | 橙子 | 新街19号 | 72754722 | 打印类型 1 |
115 | 约翰 | 橙子 | 新街11号 | 99236527 | 打印类型2 |
115 | 约翰 | 橙子 | 新街11号 | 99236527 | 打印类型2 |
按 SaleID 和 PrintType 分组,如下所示:
销售编号 | 名称 | 产品 | 地址 | 电话 | NoOfPrintType1 | NoOfPrintType2 | NoOfPrintType3 |
---|---|---|---|---|---|---|---|
112 | 乔 | 苹果 | 新街12 | 11223344 | 1个 | 3个 | 1个 |
113 | 乔 | 猕猴桃 | 新街12 | 11223344 | 0 | 0 | 1个 |
114 | 简 | 橙子 | 新街19号 | 72754722 | 1个 | 0 | 0 |
115 | 约翰 | 橙子 | 新街11号 | 99236527 | 0 | 2个 | 0 |
最好 id 喜欢使用 LINQ,但 id 也可以使用 SQL,id 只是想尽可能避免使用 for 循环。 编辑:有一定数量的打印类型,因此它不需要是动态的。
为了聚合一组 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(),
};
Linq 语句首先按 SaleId 分组,然后为每个 SaleId 创建一个 object,它包括
您可以在下面找到生成测试数据并输出结果的示例。
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" };
}
}
}
你可以使用这个 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.