2017-11-15 6 views
0

ここでSQL文を使用してカーソルに挿入しようとしています。残念ながら、この特定の割り当てにRank()関数を使用することはできません。カーソルをランク付けして使用するPL/SQLプログラム

CREATE or REPLACE PROCEDURE RankGPA 
IS 
    vSnum student.snum%type; 
    vSname student.sname%type; 
    vGPA student.GPA%type; 
    vMajor student.major%type; 
    CURSOR rankGPA_cursor IS 
    SELECT s1.snum, s1.sname, s1.gpa, count(s2.gpa) + 1 as rank, s1.major 
    FROM students s1 
    LEFT JOIN students s2 
    ON s1.GPA < s2.GPA 
    GROUP BY s1.snum, s1.sname, s1.gpa, s1.Major 
    ORDER BY 4; 
BEGIN 
    OPEN rankGPA_cursor; 
    FETCH rankGPA_cursor INTO vSnum, vSname, vGPA, vMajor; 
END; 

私はこのような出力を取得しようとしている:

Rank SNUM SNAME GPA MAJOR 
**** **** ***** *** ***** 
1 101 Bob 4  ENGR 
2 102 Cari 3.5 ENGL 
+0

学生用テーブルの別名が同じです(LEFT JOIN学生** s2 **) – Camille

+0

ありがとう、私はそれを編集しました! – Lizzie

+0

あなたはカーソルから1行しか取り出しておらず、何もしていません。アウトプットはどこに行くのですか?なぜあなたはPL/SQLをまったく使用していますか?なぜあなたは 'rank()'を使うことができないのですか?あなたは言われていない、あるいはあなたは知らないのですか?他の分析関数はどうですか? –

答えて

1

あなたのコメントのフレーズはちょっと混乱しますが、 counter変数が増加し

DECLARE 
    counter pls_integer := 0; 
    CURSOR rankGPA_cursor IS 
    SELECT s.snum, s.sname, s.gpa, s.major 
    FROM students s 
    ORDER BY s.gpa DESC; 
BEGIN 
    FOR rankGPA_row IN rankGPA_cursor LOOP 
    counter := counter + 1; 
    dbms_output.put_line(counter 
     ||' '|| rankGPA_row.snum 
     ||' '|| rankGPA_row.sname 
     ||' '|| rankGPA_row.gpa 
     ||' '|| rankGPA_row.major 
    ); 
    END LOOP; 
END; 
/

たびループ:彼らはフェッチされるようようなもの、行をカウントすることにより、「ランク」として機能するOCAL変数。カーソルクエリは、GPA の降順での順に並べ替えられているため、フェッチされた最初のローはGPAが最も高く、カウンタはそのポイントで1になります。

dbms_outputを使用すると、現実世界ではクライアントが有効になっているかどうかわからないので、印刷結果をきちんと整形するために何らかの作業を行う必要があります。しかし、これはとにかく考案されています。

また、2人の学生が同じGPAを持つ場合、どのようにランクを付けたいかを検討する必要があります。これは現在結ばれた生徒を任意にランク付けします。 order by句を変更して、たとえば名前によるセカンダリソートを追加することができます。しかし、結ばれたスコアを持つ学生はまだ異なるランクを得るでしょう。最後に見たGPAを追跡し、新しい行の値が以前のものと異なる場合にのみランク/カウンタをインクリメントすることによって、このメソッドでも同じランクを与えることは確かに可能です。私はあなたが何を生産すると思われるか分かりません。

これには任意のスタイルのカーソルを使用できます。明示的または暗黙的に、cursor-for-loopまたは明示的なオープン・フェッチをループ・クローズで使用することができます。

+0

これはとてもうまく説明されました。私はこれからたくさんのことを学んでくれてありがとう! – Lizzie

0

あなたはwindowed functionsの使用を検討できます。

SELECT s1.snum, s1.sname, s1.gpa, s1.Major,RANK() OVER(ORDER BY s1.gpa) AS r 
FROM students s1; 

RANK docから:

RANKの計算を値のグループ内の値のランク戻り値の型はNUMBERです。

1

私はempテーブルと同様のものを実行しました。あなたは、学生のテーブルのためにそれを変更することができます。

1.Withoutランク機能上:ファンクションオーバー

SELECT x.ranking,ename,sal 
FROM emp e, 
    (
SELECT e2.empno, COUNT(*) AS 
     ranking 
FROM emp e1,emp e2 WHERE e1.sal<=e2.sal 
     GROUP BY e2.empno 
)x 

WHERE e.empno=x.empno 
ORDER BY sal 

2.Withランク:

SELECT RANK() OVER (ORDER BY sal DESC) AS ranking ,empno,ename,sal 

FROM emp 

注:つながりがある場合は、あなたが使用することができますDENSE_RANK

関連する問題