从另一个表中多行的条件获取一个表上的单个结果

时间:2014-07-08 08:49:22

标签: sql oracle

想象一下学生表,其中包含学校学生的姓名和身份,以及在表格上有成绩的成绩表:

grade_id | student_id数据。

我想要做的是找到符合任意标准的所有学生"找到所有A级,B级但不是C或D"的学生。

在学校的情况下,学生可以有几个A和B,但对于我的特殊问题,他们总是会有一个或没有每个年级。

此外,我正在处理的表格很庞大(每个表中有数百万行),但我只需要在每个查询中找到10-20个(目的是查找测试数据)。 / p>

谢谢!

2 个答案:

答案 0 :(得分:1)

将表变量更改为物理表,这应该有帮助吗?

DECLARE @Students TABLE (
    StudentId INT,
    StudentName VARCHAR(50));
INSERT INTO @Students VALUES (1, 'Tom');
INSERT INTO @Students VALUES (2, 'Dick');
INSERT INTO @Students VALUES (3, 'Harry');
DECLARE @StudentGrades TABLE (
    StudentId INT,
    GradeId INT);
INSERT INTO @StudentGrades VALUES (1, 1);
INSERT INTO @StudentGrades VALUES (1, 1);
INSERT INTO @StudentGrades VALUES (1, 2);
INSERT INTO @StudentGrades VALUES (1, 3);
INSERT INTO @StudentGrades VALUES (2, 1);
INSERT INTO @StudentGrades VALUES (2, 2);
INSERT INTO @StudentGrades VALUES (3, 1);
INSERT INTO @StudentGrades VALUES (3, 1);
INSERT INTO @StudentGrades VALUES (3, 3);
INSERT INTO @StudentGrades VALUES (3, 4);
INSERT INTO @StudentGrades VALUES (3, 4);
DECLARE @Grades TABLE (
    GradeId INT,
    GradeName VARCHAR(10));
INSERT INTO @Grades VALUES (1, 'A');
INSERT INTO @Grades VALUES (2, 'B');
INSERT INTO @Grades VALUES (3, 'C');
INSERT INTO @Grades VALUES (4, 'D');

--Student/ Grade Summary
SELECT
    s.StudentId,
    s.StudentName,
    g.GradeName,
    COUNT(sg.GradeId) AS GradeCount
FROM
    @Students s
    CROSS JOIN @Grades g
    LEFT JOIN @StudentGrades sg ON sg.StudentId = s.StudentId AND sg.GradeId = g.GradeId
GROUP BY
    s.StudentId,
    s.StudentName,
    g.GradeName;

--Find ten students with A and B but not C or D
SELECT TOP 10
    *
FROM
    @Students s

WHERE
    EXISTS (SELECT * FROM @StudentGrades sg WHERE sg.StudentId = s.StudentId AND sg.GradeId = 1) --Got an A
    AND EXISTS (SELECT * FROM @StudentGrades sg WHERE sg.StudentId = s.StudentId AND sg.GradeId = 2) --Got a B
    AND NOT EXISTS (SELECT * FROM @StudentGrades sg WHERE sg.StudentId = s.StudentId AND sg.GradeId IN (3, 4)); --Didn't get a C or D

答案 1 :(得分:0)

确保您的所有ID字段都已编入索引。

select * 
from students s
where exists
    (
        select * 
        from grades g 
        where g.grade_id in (1, 2) 
        and g.student_id = s.student_id
    )