我想过滤一个查询的结果,该查询返回两个表中的结果,这两个表之间有很多关系。
请考虑以下情形:(SQL Server或MS Access)
表:学生
--StudentID
--StudentName
表:成绩
- 学生(外键)
--CourseID(外键。为了简单而忽略)
--StudentGrade(满分100分)
现在我想过滤结果并仅返回成绩均为>的学生的成绩详情。 50。
现在,我采取了以下步骤:
1 - 获取所有学生和成绩:
DataTable dtAll = GetData("SELECT * FROM Students INNER JOIN Grades ON Students.StudentID = Grades.StudentID)
2 - 让所有至少有一个成绩的学生< 50.(学生失败)
DataTable dtFailed = GetData("SELECT Distinct(Students.StudentID), Grades.StudentGrade FROM Students INNER JOIN INNER JOIN Grades ON Students.StudentID = Grades.StudentID WHERE Grades.StudentGrade < 50")
3 - 删除与失败学生相关的所有字段:
foreach (DataRow failedRow in dtFailed.Rows)
{
int counter = 0;
while (counter < dtAll.Rows.Count)
{
if (counter >= dtAll.Rows.Count)
break;
curRow = dtAll.Rows[counter];
if (Convert.ToInt32(curRow["StudentID"]) == Convert.ToInt32(failedRow["StudentlID"]))
dtAll.Rows.Remove(curRow);
else
counter += 1;
}
}
这段代码只是遍历所有dtFailed行,并删除dtAll中的行,这些行在dtFailed中有一个条目。 (如果学生至少有一门课程失败,所有学生的成绩将被删除。)
我想这是生产环境中的常见情况,希望有更快更清洁的方法。
感谢是否有人与我分享。
附:如果只能通过存储过程或任何特定于SQL的方式(不可访问)来完成,请分享,因为我可以根据需要使用SQL Server而不是MS Access。
答案 0 :(得分:1)
SELECT s.StudentId ,
s.StudentName,
g.StudentGrade
FROM Students s
JOIN Grades g
ON g.StudentID = s.StudentID
WHERE g.StudentGrade > 50
AND NOT EXISTS
(SELECT *
FROM Grades g2
WHERE g2.StudentGrade <= 50
AND g.StudentID = g2.StudentID)
答案 1 :(得分:1)
也许使用LINQ查询dtAll
而不是再次访问数据库?
//student IDs having min grade greater than 50
var studentIDs = from f in table.AsEnumerable()
group f by new { StuID = f.Field<int>("StudentID"),
StuGrade = f.Field<int>("StudentGrade") }
into g
where g.Min(x => x.Field<int>("StudentGrade") > 50)
select new
{
StudentID = g.Key.StuID,
StudentGrade = g.Key.StuGrade
};
foreach (var item in studentIDs)
{
Console.WriteLine(item.StudentID + " : " + item.StudentGrade);
}