1

このSQLクエリの開発に頭を悩ませています。次の2つのテーブルがあるとします。

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

学生が過去に合格点(C以上)で同じ(または同等の)コースを受講したことがあるかどうかを検出するための最良の方法は何でしょうか?

学生#1はコースABC001を受講し、Cの成績を取得しました。10年後、コースの名前が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

バグで投稿して申し訳ありません..それは、同等のものよりも要求された実際のコースのスコアを優先しました-今修正されました

これは1つのレベルの同等性のみを検索しますが、それを強制し、データ入力プロセスのその部分を使用したい場合があります。すべての可能な同等性を確認し、有効な同等性を入力します。

編集:予選コースの最初のパス(番号付きの用語を使用)

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が必要であることに注意してください)

于 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 に答える