SQL - 查找具有等效性的重复项

时间:2012-04-23 13:48:11

标签: sql

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

  • Acade_HISTORY(STUDENT_ID,TERM,COURSE_ID,COURS_GRADE)
  • COURSE_EQUIVALENCIES(COURS_ID,COURS_ID_EQUIVALENT)

如果学生在过去的成绩(C或更高)中采用相同的( 或同等的 )课程,最好的方法是什么?

实施例

学生#1参加ABC001课程并获得C等级。十年后,课程重新命名为ABC011,并在COURSE_EQUIVALENCIES中录制了相应的参赛作品。学生以这个新名称重新学习该课程,并获得了B级。我如何构建一个SQL查询来检测重复的课程并只计算第一个及格分数?

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

提前致谢。

修改 甚至没有必要保留或丢弃任何信息。只显示带有重复项的类的查询就足够了。

2 个答案:

答案 0 :(得分: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是MySQL的t-sql命令,你需要LIMIT)

答案 1 :(得分:0)

数据(在LOWERCASE中)

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)