我想只检索具有不可接受成绩的学生。我的原始查询是:
SELECT ssm.STUDENT_ID,COUNT(srcg.GRADE_TITLE) AS POSTED_GRADES
FROM STUDENT_ENROLLMENT ssm, STUDENT_REPORT_CARD_GRADES srcg
WHERE ssm.SYEAR='2010'
AND ssm.SCHOOL_ID='12'
AND ssm.GRADE_ID IN ('140','141','142','143','144','145')
AND srcg.STUDENT_ID=ssm.STUDENT_ID
AND srcg.SYEAR='2010'
AND srcg.SCHOOL_ID='12'
AND srcg.MARKING_PERIOD_ID='434'
AND srcg.GRADE_TITLE IN ('1','2','F','D')
GROUP BY ssm.STUDENT_ID;
但我不关心伯爵;我只想找到成绩不好的学生。我正在尝试另一个查询:
SELECT ssm.STUDENT_ID
FROM STUDENT_ENROLLMENT ssm
WHERE ssm.SYEAR='2010'
AND ssm.SCHOOL_ID='12'
AND ssm.GRADE_ID IN ('140','141','142','143','144','145')
AND EXISTS(SELECT srcg.GRADE_TITLE from STUDENT_REPORT_CARD_GRADES srcg, STUDENT_ENROLLMENT ssm
WHERE srcg.STUDENT_ID=ssm.STUDENT_ID
AND srcg.SYEAR='2010'
AND srcg.SCHOOL_ID='12'
AND srcg.MARKING_PERIOD_ID='434'
AND srcg.GRADE_TITLE IN ('1','2','F','D'));
但它会返回更多记录,所以显然我做错了。有没有办法使用EXISTS,它将返回与第一个查询相同的结果但效率更高?
答案 0 :(得分:0)
您可以获得更多记录,因为您没有像使用GROUP BY
的第一个查询中那样删除重复项。重新放入GROUP BY
,或添加DISTINCT
,看看它是如何运作的。
答案 1 :(得分:0)
您可以删除exists子句中的student_enrollment
连接。
SELECT ssm.STUDENT_ID, COUNT(*) AS POSTED_GRADES
FROM STUDENT_ENROLLMENT ssm
WHERE ssm.SYEAR = '2010'
AND ssm.SCHOOL_ID = '12'
AND ssm.GRADE_ID IN ('140','141','142','143','144','145')
AND EXISTS(SELECT srcg.GRADE_TITLE
from STUDENT_REPORT_CARD_GRADES srcg
WHERE srcg.SYEAR = '2010'
AND srcg.SCHOOL_ID = '12'
AND srcg.MARKING_PERIOD_ID = '434'
AND srcg.GRADE_TITLE IN ('1','2','F','D')
);
GROUP BY ssm.STUDENT_ID
如果STUDENT_REPORT_CARD_GRADES表很大,这可能会更快。
答案 2 :(得分:0)
我长期以来一直不喜欢“与众不同”,因为它过去曾隐藏过我的错误。我推荐这个:
select STUDENT_ID from
(SELECT ssm.STUDENT_ID,COUNT(srcg.GRADE_TITLE) AS POSTED_GRADES
FROM STUDENT_ENROLLMENT ssm, STUDENT_REPORT_CARD_GRADES srcg
WHERE ssm.SYEAR='2010'
AND ssm.SCHOOL_ID='12'
AND ssm.GRADE_ID IN ('140','141','142','143','144','145')
AND srcg.STUDENT_ID=ssm.STUDENT_ID
AND srcg.SYEAR='2010'
AND srcg.SCHOOL_ID='12'
AND srcg.MARKING_PERIOD_ID='434'
AND srcg.GRADE_TITLE IN ('1','2','F','D')
GROUP BY ssm.STUDENT_ID);
答案 3 :(得分:0)
根据我的经验,如果您对效率感兴趣,则不应该使用EXISTS。请尝试以下方法:
SELECT DISTINCT ssm.STUDENT_ID
FROM STUDENT_ENROLLMENT ssm
INNER JOIN STUDENT_REPORT_CARD_GRADES srcg
ON (srcg.STUDENT_ID = ssm.STUDENT_ID)
WHERE ssm.SYEAR='2010' AND
ssm.SCHOOL_ID = '12' AND
ssm.GRADE_ID IN ('140','141','142','143','144','145') AND
srcg.SYEAR='2010' AND
srcg.SCHOOL_ID = '12' AND
srcg.MARKING_PERIOD_ID = '434' AND
srcg.GRADE_TITLE IN ('1','2','F','D')
确保您在以下字段或字段组中包含索引:
另外,请确保您使用的常量与所涉及的列的数据类型相匹配。此语句中的所有常量都以字符串形式给出 - 所有字段都是字符列,还是数字(例如,STUDENT_ENROLLMENT.SYEAR)?强制数据库执行不必要的转换会导致它执行一些真正可怕的事情,例如将数字列值转换为字符串,以便将转换后的列值与字符串常量进行比较。这可以保证表扫描速度非常慢,性能可怕。
分享并享受。
答案 4 :(得分:0)
尝试这个
SELECT distinct ssm.STUDENT_ID
FROM STUDENT_ENROLLMENT ssm, STUDENT_REPORT_CARD_GRADES srcg
WHERE ssm.SYEAR='2010'
AND ssm.SCHOOL_ID='12'
AND ssm.GRADE_ID IN ('140','141','142','143','144','145')
AND srcg.STUDENT_ID=ssm.STUDENT_ID
AND srcg.SYEAR= ssm.SYEAR
AND srcg.SCHOOL_ID=ssm.SCHOOL_ID
AND srcg.MARKING_PERIOD_ID='434'
AND srcg.GRADE_TITLE IN ('1','2','F','D')