2011-06-23 9 views
1

注:私の研究はthis questionとなりました。これは私の問題を解決する可能性がありますが、私の質問はもっと一般的です。をやる?SELECT文で作成した列に参加するときに「無効な識別子」が表示される

私は学力データベースを照会して、特定の生徒が採択した微積分クラスの各ペアについて、そのレコードが他のものの前提条件であることを記録したいと思います。データベースがうまく設定したり、コース番号は合理的だった場合、私は何ができる:

SELECT ... 
FROM Academic_History PrerequisiteCourse 
JOIN Academic_History NextCourse 
    ON (NextCourse.CalculusLevel = PrerequisiteCourse.CalculusLevel + 1) 
WHERE ... 

もちろんCalculusLevelフィールドが存在しないので、これはナンセンスです。また、Calculus Iとして認定されるいくつかのコース番号があります。また、Calculus IIなどとして認定されるいくつかのコース番号があり、これらはかなり頻繁に変更されます。ずっと容易になるだろうされ、その場で私の「CalculusLevel」フィールドを私は私ように感じるが作成されないはずです

SELECT ... 
FROM Academic_History PrerequisiteCourse 
JOIN Academic_History NextCourse 
    ON (NextCourse.CourseNumber = '231' AND PrerequisiteCourse.CourseNumber = '220' 
     OR NextCourse.CourseNumber = '231' AND PrerequisiteCourse.CourseNumber = '221' 
     OR NextCourse.CourseNumber = '241' AND PrerequisiteCourse.CourseNumber = '231' 
     OR NextCourse.CourseNumber = '24-' AND PrerequisiteCourse.CourseNumber = '231' 
     ...) 
WHERE ... 

:それは、これは本当に悪い考えのような結合文にすべての前提条件のペアリングをハードコーディングせ

SELECT CASE PrerequisiteCourse.CRS_NBR 
      WHEN '115' THEN '0' 
      WHEN '220' THEN '1' 
      WHEN '221' THEN '1' 
      ... 
      END PrerequisiteCourseLevel, 
     CASE NextCourse.CRS_NBR 
      WHEN '115' THEN '0' 
      WHEN '220' THEN '1' 
      WHEN '221' THEN '1' 
      ... 
      END NextCourseLevel, 

FROM Academic_History PrerequisiteCourse 
JOIN Academic_History NextCourse 
    ON (PrerequisiteCourseLevel + 1 = NextCourseLevel) 
WHERE ... 

もちろん、これらの列はこれらの表にないため、結合は機能しません。 JOIN ONからWHERE節に条件を移しても、WHERE句が実行されているときにこれらのフィールドが存在しないため、「無効な識別子」エラーが表示されます。

これは正しい方法はありますか?私は2番目のコードブロックで言及したようないくつかのソリューションを考え出しましたが、彼らはすべて専門家でないハックのように感じます。

ありがとうございます!

+0

わからない何」ここで尋ねるこれはデータモデリングの問題のように思えますが、なぜそれを構文質問としてフレームに入れましたか? – APC

+0

私は、私の次のバージョンがGoogleを介してそれを見つけるようなタイトルを語ろうとしました。私の質問は、「コードブロック#2で醜いハッキングを使用すべきか、リンクされた質問に醜いハックを使用すべきか、実際にはこれを行うには良い方法があるのか​​」 –

+1

これらのコースのレベルを醜いケースの声明で維持するのではなく、テーブル自体に追加することを検討しましたか? –

答えて

2

あなたはCTE使用して、再利用可能な列を追加することができます。

;with hist as 
     (
     select case ... end as NextCourseLevel 
     ,  case ... end as PrerequisiteCourseLevel 
     ,  * 
     from Academic_History 
     ) 
select * 
from hist t1 
join hist t2 
on  t1.PrerequisiteCourseLevel + 1 = t2.NextCourseLevel 

EDITを:あなたのコメントにつき、あなたはそれが使われてどこにでもそれの拡大with声明をリファクタリングすることができます

select * 
from (
     select case ... end as PrerequisiteCourseLevel 
     ,  * 
     from Academic_History 
     ) as t1 
join (
     select case ... end as NextCourseLevel 
     ,  * 
     from Academic_History 
     ) as t2 
on  t1.PrerequisiteCourseLevel + 1 = t2.NextCourseLevel 
+0

これは素晴らしいと思われ、おそらくこの問題を抱えている将来の人々のための正しい答えです。残念ながら、データベースへのアクセスは実際にSELECTステートメントに限定されていることがわかりました。サブクエリの処理はほとんど同じですが、おそらく本質的に同じです。 –

+0

ああ、私のあいまいなフォローアップの質問はうまく対処されています[ここ](http://stackoverflow.com/questions/706972/difference-between-cte-and-subquery)。 –

+1

「ビューを作成」権限を要求し、派生したCalculusLevelデータを公開するビューを作成します。別のコースを追加する必要がある場合は、派生データを必要とするすべてのクエリではなくビューを変更するだけです。Oracleの – Phil