【问题标题】:Getting a single result on one table from criteria on multiple rows in another table从另一个表中多行的条件中获取一个表的单个结果
【发布时间】:2014-07-08 08:49:21
【问题描述】:

想象一个 Student 表,其中包含学校学生的姓名和 ID,以及一个 Grades 表,其中包含表格上的成绩:

grade_id | student_id。

我想要做的是找到所有符合任意条件的学生,比如“找到所有成绩为 A、B,但不是 C 或 D 的学生”。

在学校情况下,一个学生可能有几个 A 和 B,但对于我的特殊问题,他们总是每个成绩都只有一个或没有。

另外,我正在处理的表很大(每个表有几百万行),但我只需要在每个查询中找到 10-20 行(这样做的目的是查找测试数据)。

谢谢!

【问题讨论】:

  • 那么,一个学生有A级(真/假)、B级(真/假)、C级(真/假)、D级(真/假)?

标签: sql oracle


【解决方案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

【讨论】:

  • 只是出于好奇,那是什么 SQL 方言?
【解决方案2】:

确保您的所有 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
    )

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多