C# 在两列上分组并创建两个单独的计数 问题:
我们有一个包含C# 在两列上分组并创建两个单独的计数 问题:,c#,linq,C#,Linq,我们有一个包含学生ID和讲师ID的表格,我们想知道两件事 CountStudentId每个StudentId发生多少次 countstudentidlectreid每对StudentId+讲师ID出现多少次 (2) 是在下面完成的。(1) 事实并非如此 换句话说,我们如何在一个查询中计算两个不同的组? 另一种思考方法是计算学生ID+讲师ID组,并将每个学生ID的计数相加 我们试过的 以下查询组位于StudentId+讲师ID。它会计算StudentId+讲师ID组出现的次数。它不计算Studen
学生ID
和讲师ID
的表格,我们想知道两件事
CountStudentId
每个StudentId
发生多少次countstudentidlectreid
每对StudentId
+讲师ID
出现多少次学生ID
+讲师ID
组,并将每个学生ID
的计数相加
我们试过的
以下查询组位于StudentId
+讲师ID
。它会计算StudentId
+讲师ID
组出现的次数。它不计算StudentId
组出现的次数。这也是我们想要的
var query = joinTable
.GroupBy(jt => new { jt.StudentId, jt.LectureId } )
.Select(g => new {
StudentId = g.Key.StudentId,
LectureId = g.Key.LectureId,
CountStudentId = -1, // Count all StudentId (i.e. 10)?
CountStudentIdLectureId = g.Count()
});
这是我们目前收到的结果。在每一行中,-1
值应该是10
(因为我们在连接表中为每个StudentId
添加了10个种子),但我们还没有实现这一点
我们希望取得的成果
…但在每种情况下都使用10
而不是-1
**
StudentId LectureId CountStudentId CountStudentLectureId
0 0 -1 3
0 1 -1 3
0 2 -1 3
0 3 -1 1
1 0 -1 2
1 1 -1 3
1 2 -1 3
1 3 -1 2
在这些结果中,我们需要CountStudentId
成为10
而不是-1
(后者目前只是一个占位符)
这是预期的结果,因为每个StudentId
发生10次,而且每个StudentId
的countstudent讲师ID
之和是10
,这只是说同一件事的两种方式
完整演示代码
这是供参考的最新版本
using System;
using System.Linq;
using System.Collections.Generic;
public static class Program
{
public static void Main()
{
var joinTable = SeedJoinTable();
var query = joinTable
.GroupBy(jt => new { jt.StudentId, jt.LectureId } )
.Select(g => new {
StudentId = g.Key.StudentId,
LectureId = g.Key.LectureId,
CountStudentId = -1, // Count all StudentId (i.e. 10)?
CountStudentIdLectureId = g.Count()
});
// this is just the printing of the results
Console.WriteLine(
"StudentId".PadRight(15) +
"LectureId".PadRight(15) +
"CountStudentId".PadRight(17) +
"CountStudentLectureId".PadRight(15));
foreach(var x in query)
{
Console.WriteLine(string.Format("{0}{1}{2}{3}",
x.StudentId.ToString().PadRight(15),
x.LectureId.ToString().PadRight(15),
x.CountStudentId.ToString().PadRight(17),
x.CountStudentIdLectureId.ToString().PadRight(15)));
}
}
public static List<JoinTable> SeedJoinTable()
{
var list = new List<JoinTable>();
var studentId = 0;
var lectureId = 0;
// insert 20 records
for(int i = 0; i < 20; ++i)
{
if(i != 0)
{
if(i % 10 == 0)
{
// 10 of each studentId
++studentId;
lectureId = 0;
}
if(i % 3 == 0)
{
// 3 of each lectureId per student
++lectureId;
}
}
list.Add(new JoinTable() {
StudentId = studentId,
LectureId = lectureId
});
}
return list;
}
public class JoinTable
{
public int StudentId { get; set; }
public int LectureId { get; set; }
}
}
使用系统;
使用System.Linq;
使用System.Collections.Generic;
公共静态类程序
{
公共静态void Main()
{
var joinTable=SeedJoinTable();
var query=joinTable
.GroupBy(jt=>new{jt.StudentId,jt.讲师ID})
.选择(g=>new{
StudentId=g.Key.StudentId,
讲师ID=g.Key.讲师ID,
CountStudentId=-1,//计算所有StudentId(即10)?
CountStudentIdLectureId=g.Count()
});
//这只是结果的打印
控制台写入线(
“学生ID”,右键(15)+
“讲师”,右键(15)+
“CountStudentId”,右键(17)+
“CountStudent讲师”(PadRight(15));
foreach(查询中的变量x)
{
Console.WriteLine(string.Format(“{0}{1}{2}{3}”),
x、 StudentId.ToString().PadRight(15),
x、 ToString().PadRight(15),
x、 CountStudentId.ToString().PadRight(17),
x、 CountStudentIdLectureId.ToString().PadRight(15));
}
}
公共静态列表SeedJoinTable()
{
var list=新列表();
var studentId=0;
var=0;
//插入20条记录
对于(int i=0;i<20;++i)
{
如果(i!=0)
{
如果(i%10==0)
{
//每个学生10人
++学生;
平均值=0;
}
如果(i%3==0)
{
//每名学生每人3名
++开斋节;
}
}
添加(新的JoinTable(){
StudentId=StudentId,
讲师ID=讲师ID
});
}
退货清单;
}
公共类可联接
{
公共int StudentId{get;set;}
公共ID{get;set;}
}
}
这是一个例子
您将希望按StudentId分组,并将值设置为“讲师ID”。这允许您获取studentId和studentIdLectureId对的计数
var query = joinTable
.GroupBy(jt => jt.StudentId, jt => jt.LectureId)
.Select(x =>
new {
StudentId = x.Key,
CountStudentId = x.Count(),
LectureIds = x.GroupBy(y => y),
});
这确实会改变在最终列表中循环的方式,但会为您提供相同数据和相同数量的循环:
foreach(var x in query)
{
foreach(var lectureId in x.LectureIds)
{
Console.WriteLine(string.Format("{0}{1}{2}{3}",
x.StudentId.ToString().PadRight(15),
lectureId.Key.ToString().PadRight(15),
x.CountStudentId.ToString().PadRight(17),
lectureId.Count().ToString().PadRight(15)));
}
}
如果您想在讲师ID中包含任何内容(讲座名称、教授等),您可以这样做:
var query = joinTable
.GroupBy(jt => jt.StudentId, jt => new {LectureId = jt.LectureId, ProfessorId = jt.ProfessorId})
.Select(x =>
new {
StudentId = x.Key,
CountStudentId = x.Count(),
LectureIds = x.GroupBy(y => y),
});
假设表中没有重复项,那么简单的GroupByStudentId
就是您想要的:var query=joinTable.GroupBy(t=>t.StudentId)代码>如何:Console.WriteLine(“CountStudentId:+joinTable.Select(ab=>ab.StudentId.Distinct().Count())
CountStudentId=g.Select(x=>x.StudentId).Count(),我不明白是什么问题。你想在一行中完成吗?为什么?CountStudentId
只是可连接的。选择(t=>t.StudentId).Distinct().Count()
,就这么简单。我不明白你从哪里得到这个10,恐怕不行。下面是一个例子,演示了当studentId
和讲师ID
都为零时,当预期计数为3
时,您的查询将显示4
的计数。我不知道为什么。。。在适当的时候,也许我们会一起解决这个问题。我更新了代码,以便在小组中获得讲座id。在处理过程中,我进行了一次迭代,计算该学生的唯一课堂id,而不是学生/课堂id组合的数量。我发表了一篇错误的文章。抱歉搞混了!知道了。我只需要在您的代码中做一个更改。如果您感兴趣,这里有一个相关的未回答问题,您也可以回答: