我们有StudentId
和LectureId
的表格,我们想知道两件事。
CountStudentId
每个StudentId
出现多少次。CountStudentIdLectureId
每个StudentId
+ LectureId
对出现多少次。(2)在下面完成。 (1)不是。
换句话说,如何在一个查询中统计两个不同的群组?
另一种思考方式是计算StudentId
+ LectureId
组,并将每个StudentId
的计数加起来。
StudentId
+ LectureId
上的以下查询组。它会计算StudentId
+ LectureId
组的出现次数。它不会计算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
(因为我们将每个JoinTable
中的十个StudentId
播种到了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
出现CountStudentLectureId
次,因为每个StudentId
的{{1}}总和为10
,这只是两种说法相同的方式。
这是full Fiddle code供参考。
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; }
}
}
答案 0 :(得分:2)
这是working DotNotFiddle that produces the results that you want to achieve。
您需要按StudentId进行分组,并将值设置为LectureId。这允许您获得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)));
}
}
如果你想在讲座(讲座名,教授等)中加入任何内容,你可以这样做:
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),
});