1

我在开发这个 SQL 查询时遇到了麻烦。给定以下两个表:

  • ACADEMIC_HISTORY (STUDENT_ID, TERM, COURSE_ID, COURSE_GRADE)
  • COURSE_EQUIVALENCIES (COURSE_ID, COURSE_ID_EQUIVALENT)

检测学生过去是否参加过相同(或同等)课程且成绩及格(C 或更高)的最佳方法是什么?

例子

学生 #1 参加了 ABC001 课程并获得了 C 的成绩。十年后,该课程更名为 ABC011,并在 COURSE_EQUIVALENCIES 中输入了相应的条目。学生以这个新名称重新学习了课程并获得了 B 级。我如何构建一个 SQL 查询来检测重复的课程并且只计算第一个及格的成绩?

(实际情况要复杂得多,但这应该让我开始。)

提前致谢。

编辑: 甚至没有必要保留或丢弃任何信息。仅显示具有重复项的类的查询就足够了。

4

2 回答 2

1

你可以使用类似的东西:

SELECT 
    STUDENT_ID
    ,MIN (COURSE_GRADE)
FROM (
    SELECT * FROM         
        ACADEMIC_HISTORY 
    WHERE COURSE_ID =1

    UNION

    SELECT 
        h.STUDENT_ID
        ,h2.COURSE_ID
        ,h2.COURSE_GRADE
    FROM
    ACADEMIC_HISTORY AS h
    LEFT OUTER JOIN COURSE_EQUIVELANCIES as e
        ON e.COURSE_ID = h.COURSE_ID
    LEFT OUTER JOIN ACADEMIC_HISTORY as h2
        ON h.STUDENT_ID = h2.STUDENT_ID
        AND h2.COURSE_ID = e.COURSE_ID_EQUIVELANT
    WHERE
         h.COURSE_ID =1
) AS t
WHERE STUDENT_ID =1
GROUP BY STUDENT_ID

http://sqlfiddle.com/#!3/d608f/20

抱歉发布了一个错误..它更喜欢实际课程的分数而不是任何等效分数 - 现在已修复

这只寻找一个等价级别..但也许你想强制执行并拥有数据输入过程的那部分..查看所有可能的等价并输入有效的

编辑:第一次通过资格课程(使用编号条款..)

SELECT TOP 1
    STUDENT_ID
    ,MIN (COURSE_GRADE)
FROM (
    SELECT * FROM         
        ACADEMIC_HISTORY 
    WHERE COURSE_ID =1

    UNION

    SELECT 
        h.STUDENT_ID
        ,h2.COURSE_ID
        ,h2.TERM
        ,h2.COURSE_GRADE
    FROM
    ACADEMIC_HISTORY AS h
    LEFT OUTER JOIN COURSE_EQUIVELANCIES as e
        ON e.COURSE_ID = h.COURSE_ID
    LEFT OUTER JOIN ACADEMIC_HISTORY as h2
        ON h.STUDENT_ID = h2.STUDENT_ID
        AND h2.COURSE_ID = e.COURSE_ID_EQUIVELANT
    WHERE
         h.COURSE_ID =1
) AS t
WHERE STUDENT_ID =1

GROUP BY STUDENT_ID, TERM
ORDER BY TERM ASC

http://sqlfiddle.com/#!3/fdded/6

(注意 TOP 是你需要 LIMIT 的 MySQL 的 t-sql 命令)

于 2012-04-23T14:08:32.313 回答
0

数据(小写)

DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp;
SET search_path='tmp';

CREATE TABLE academic_history
        ( student_id INTEGER NOT NULL
        , course_id CHAR(6)
        , course_grade CHAR(1)
        , PRIMARY KEY(student_id,course_id)
        );
INSERT INTO academic_history ( student_id,course_id,course_grade) VALUES
 (1, 'ABC001' , 'C' )
 , (1, 'ABC011' , 'B' )
 , (2, 'ABC011' , 'A' )
        ;

CREATE TABLE course_equivalencies
        ( course_id CHAR(6)
        , course_id_equivalent  CHAR(6)
        );
INSERT INTO course_equivalencies(course_id,course_id_equivalent) VALUES
        ( 'ABC011' , 'ABC001' )
        ;

查询:

-- EXPLAIN ANALYZE
WITH canon AS (
        SELECT ah.student_id AS student_id
        , ah.course_id AS course_id
        , COALESCE (eq.course_id_equivalent,ah.course_id) AS course_id_equivalent
        FROM academic_history ah
        LEFT JOIN course_equivalencies eq ON eq.course_id = ah.course_id
        )
SELECT h.student_id
        , c.course_id_equivalent
        , MIN(h.course_grade) AS the_grade
FROM academic_history h
JOIN canon c ON c.student_id = h.student_id AND c.course_id = h.course_id
GROUP BY h.student_id, c.course_id_equivalent
ORDER BY h.student_id, c.course_id_equivalent
        ;

输出:

NOTICE:  drop cascades to 2 other objects
DETAIL:  drop cascades to table tmp.academic_history
drop cascades to table tmp.course_equivalencies
DROP SCHEMA
CREATE SCHEMA
SET
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "academic_history_pkey" for table "academic_history"
CREATE TABLE
INSERT 0 3
CREATE TABLE
INSERT 0 1
 student_id | course_id_equivalent | the_grade 
------------+----------------------+-----------
          1 | ABC001               | B
          2 | ABC001               | A
(2 rows)
于 2012-04-23T16:37:05.697 回答