0

次のSQLで正常に機能しているテーブルで名前と姓を選択する必要がありますが、機能していない部分はNVL関数です。ファイルには、ヘリコプターを操縦する会社のすべてのパイロットが表示され、ライセンスがない場合は、フィールドHT_NAMEが「N / A」として表示され、飛行終了時間のフィールドは0になります。NVL機能を設定しました。私のテキストの詳細として入力しますが、それでも機能していません。構文エラーが発生しましたか?助けていただければ幸いです。

Select E.EMP_NBR, E.EMP_FIRSTNAME || ' ' || E.EMP_LASTNAME, E.EMP_PILOT,
       ED.HT_NBR, NVL(HT.HT_NAME, 'N/A'), NVL(ED.END_HRS_FLOWN, 0),
       ED.END_LAST_ANNUAL_REVIEW_DATE
From  ENDORSEMENT ED, EMPLOYEE E, HELICOPTER_TYPE HT
WHERE HT.HT_NBR = ED.HT_NBR (+)
ORDER BY ED.END_HRS_FLOWN DESC, E.EMP_FIRSTNAME || ' ' || E.EMP_LASTNAME ASC;

パイロットではない従業員は、ヘリタイプではN / A、飛行時間では0で表示されるようにする必要があります。それは機能していません-私はそれを修復するために複数のことを試みましたが。

4

3 に答える 3

1

3 つのテーブルがあり、結合条件は 1 つだけです。Employee と Endorsement の間の結合が必要です。それがないと、これらのテーブル間でクロス積またはデカルト結合が発生します。

N テーブル (N > 0) の場合、少なくとも J = N-1 結合条件が必要です。N = 3 個のテーブルがありますが、J = 1 個の結合条件があります。これは少なすぎます。(J > N - 1 が必要な理由はさまざまですが、主な理由は、2 つのテーブル間で 2 つの列を結合する必要があるためです。各「A.Col1 = B.Col2」条件を個別の結合条件としてカウントする場合の場合、J > N-1 が必要です。条件のペア 'A.Col1 = B.Col2 AND A.Col3 = B.Col4' を 1 つの結合条件として数えると、必要なのは J = N-1 だけです条件です。)

理想的には、「(+)」を使用する古風で非標準の外部結合表記法から離れ、標準の SQL 結合を使用する必要もあります。


表記は二次的な問題です。Employee のすべての行が Endorsement のすべての行と結合され、その交差積が Helicopter_type で外部結合されます。これは (ほぼ確実に) 必要なクエリではありません。

おそらく、これのいくつかのバリエーションを WHERE 句に追加する必要があります。

AND E.EMP_NBR = ED.EMP_NBR

(Endorsement (ED) テーブルの実際の列はクエリに表示されないため、「ED.EMP_NBR」は推測です)。

他の効果の中でも特に、データベースにヘリコプターのパイロットがいる場合、すべての従業員レコードがパイロットの承認と結合されることがあります。並べ替え順序は、それらのレコードが無数のレコードの前に表示されることを意味します。パイロットにはヘリコプターの承認がなく、非パイロットにはヘリコプターの記録がないなど...

于 2010-06-10T08:14:19.663 に答える
1

@Jonathanが言ったように、WHERE句に何かを追加して、EMPLOYEEとENDORSEMENTを一致させる方法をデータベースに伝える必要があります。説明のために、両方で EMP_NBR フィールドを使用しますが、正しいフィールドを使用するようにクエリを変更する必要があります。また、従業員が有効なライセンスを持っているかどうかを示すフィールドを知る必要があります。これは ENDORSEMENT テーブルにあるものだと思います。説明のために ENDORSEMENT.LICENSE_TYPE と呼びましょう。次のように、NVL2 関数を使用して、クエリによって返される値を適切に変更できることがわかったら、次のようにします。

SELECT E.EMP_NBR,
       E.EMP_FIRSTNAME || ' ' || E.EMP_LASTNAME AS FIRST_LAST_NAME,
       E.EMP_PILOT, 
       ED.HT_NBR,
       NVL2(ED.LICENSE_TYPE, HT.HT_NAME, 'N/A') HELO_TYPE,
       NVL2(ED.LICENSE_TYPE, ED.END_HRS_FLOWN, 0) FLOWN_HOURS, 
       ED.END_LAST_ANNUAL_REVIEW_DATE 
  FROM ENDORSEMENT ED,
       EMPLOYEE E,
       HELICOPTER_TYPE HT 
  WHERE HT.HT_NBR = ED.HT_NBR (+) AND
        ED.EMP_NBR = E.EMP_NBR (+)
  ORDER BY ED.END_HRS_FLOWN DESC,
           E.EMP_LASTNAME ASC,
           E.EMP_FIRSTNAME ASC;

また、ORDER BY 句を変更して、従業員をより通常の方法で注文できるようにしました。

共有してお楽しみください。

于 2010-06-10T11:32:26.680 に答える
0

HT_NAME と END_HRS_FLOWN が、N/A または 0 と予想される行に対して null 値を持っていたかどうかを確認します

編集 1

Oracle では、NVL 関数を使用すると、NULL 値が検出されたときに値を置き換えることができます。

NVL 関数の構文は次のとおりです。

NVL( string1, replace_with )

string1は、null 値をテストする文字列です。

replace_withは、string1 が null の場合に返される値です。

値がnullでない場合、同じ値を返します

于 2010-06-10T08:28:50.817 に答える