我的SQL技能非常有限。我是技术学院计算机科学的第二年。我正在构建一个Windows窗体应用程序,允许我学院的BAS主管跟踪学生及其在整个课程中的进度。我完全可以控制数据库设计,所以如果你想到一种方法来帮助我找到一个可能涉及调整数据库的解决方案。
我正在尝试在Students
EnrollmentStatus
Courses
的所有CreditSection
中选择没有1
3的所有CreditSection
}}。共有12门课程1
SELECT * FROM Students WHERE each student has 12 entries in CourseEnrollment AND
CourseEnrollment.EnrollmentStatus = 3 AND Courses.CreditSection = 1
我正在使用的表格如下:
我可以想出几种方法来获得我的解决方案,但似乎无法将它们写成SQL:
SELECT * FROM Students WHERE Courses.CourseID 1 thru 12 EXIST in
CourseEnrollment for each student AND CourseEnrollment.EnrollmentStatus = 3
或
SELECT DISTINCT s.* FROM Students s
WHERE s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 1 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 2 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 3 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 4 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 5 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 6 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 7 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 8 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 9 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 10 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 11 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 12 AND ce.EnrollmentStatus = 3) OR
s.StudentID NOT IN (SELECT ce.StudentID FROM CourseEnrollment ce WHERE ce.CourseID = 13 AND ce.EnrollmentStatus = 3)
我可以使用下面的这个混乱来达到理想的解决方案,但是当我检查已经完成了4年课程的学生时...这个查询变得非常漫长并且可能消耗大量资源。
此查询选择不在已完成一门或多门课程的学生列表中的学生:
var query =
from student in datStudents.Students.AsEnumerable<dsStudentManager.StudentsRow>()
where !(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 1 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 2 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 3 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 4 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 5 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 6 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 7 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 8 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 9 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 10 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 11 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 12 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID) ||
!(from ce2 in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() where ce2.CourseID == 13 && ce2.EnrollmentStatus == 3 select ce2.Field<int>("StudentID")).Contains<int>(student.StudentID)
select new
{
id = student.StudentID,
rtcid = student.RTCStudentID,
firstname = student.FirstName,
lastname = student.LastName,
phone = student.Phone,
studentemail = student.StudentEmail,
personalemail = student.PersonalEmail,
address = student.Address,
city = student.City,
state = student.State,
zip = student.Zip,
birthdate = student.BirthDate,
gender = student.Gender,
notes = student.Notes,
studentdocumentslocation = student.StudentDocumentsLocation
};
我的目标是弄清楚如何在SQL中编写此查询,然后将其转换为LINQ,这最终是我需要的。如果有人可以帮助解决这一问题,我将不胜感激。
我已将上述内容转换为LINQ,它看起来同样可怕:
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
if (Utils.hasIceCreamSandwich())
searchMenuItem.expandActionView();
else MenuItemCompat.expandActionView(searchMenuItem);
答案 0 :(得分:4)
使用带有group by和having语句的子查询,你可以得到类似的东西:
SELECT * FROM Students WHERE StudentID NOT IN (
SELECT s.StudentID FROM Students s
JOIN CourseEnrollment ce ON s.StudentID = ce.StudentID
JOIN Courses c ON ce.CourseID = c.CourseID
WHERE ce.EnrollmentStatus = 3 AND c.CreditSection = 1
GROUP BY s.StudentID
HAVING COUNT(*) = 12
)
内部查询构建了学生返回的标准,“HAVING COUNT(*)= 12”可以让学生找到匹配12门课程的学生。如果您只是课程的一部分,您也可以尝试以下方法。
SELECT * FROM Students WHERE StudentID NOT IN (
SELECT s.StudentID FROM Students s
JOIN CourseEnrollment ce ON s.StudentID = ce.StudentID
JOIN Courses c ON ce.CourseID = c.CourseID
WHERE ce.EnrollmentStatus = 3 AND c.CreditSection = 1
AND c.CourseID IN (1,2,3,4,5,6,7,8)
GROUP BY s.StudentID
HAVING COUNT(*) = 8 -- Number of courses in the ID in clause
)
希望这有助于您走上正轨。
答案 1 :(得分:2)
尝试这样的东西,我手工打字,所以可能会有拼写错误。
SELECT * FROM Students s
inner join (select StudentID, count(0) as CrsEnrollCount
from CourseEnrollment ce
inner join Courses c
on ce.CourseID = c.CourseID
where ce.EnrollmentStatus = 3 AND Courses.CreditSection = 1) cnt
on cnt.StudentID = s.StudentID
where CrsEnrollCount < 12
答案 2 :(得分:0)
对于记录,这个T-SQL:
SELECT * FROM Students WHERE StudentID NOT IN (
SELECT s.StudentID FROM Students s
JOIN CourseEnrollment ce ON s.StudentID = ce.StudentID
JOIN Courses c ON ce.CourseID = c.CourseID
WHERE ce.EnrollmentStatus = 3 AND c.CreditSection = 1
GROUP BY s.StudentID
HAVING COUNT(*) = 12
)
成为这个LINQ:
var query =
from student in datStudents.Students.AsEnumerable<dsStudentManager.StudentsRow>()
where !(from s2 in datStudents.Students.AsEnumerable<dsStudentManager.StudentsRow>()
join ce in datStudents.CourseEnrollment.AsEnumerable<dsStudentManager.CourseEnrollmentRow>() on student.StudentID equals ce.StudentID
join c in datStudents.Courses.AsEnumerable<dsStudentManager.CoursesRow>() on ce.CourseID equals c.CourseID
where ce.EnrollmentStatus == 3 && c.CreditSection == 1
group s2 by s2.StudentID into s3
where s3.Count() == 12
select s3.Key).Contains<int>(student.StudentID)
select new
{
id = student.StudentID,
rtcid = student.RTCStudentID,
firstname = student.FirstName,
lastname = student.LastName,
phone = student.Phone,
studentemail = student.StudentEmail,
personalemail = student.PersonalEmail,
address = student.Address,
city = student.City,
state = student.State,
zip = student.Zip,
birthdate = student.BirthDate,
gender = student.Gender,
notes = student.Notes,
studentdocumentslocation = student.StudentDocumentsLocation
};
据我所知,这是正确的。无论如何,它会产生预期的效果。