Используя функцию NVL в SQL, помогите! - PullRequest
0 голосов
/ 10 июня 2010

Мне нужно выбрать имя и фамилию в таблице, которая отлично работает в следующем 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 для типа heli и 0 для летного времени.Это не работает - хотя я пытался несколько вещей, чтобы восстановить его.

Ответы [ 3 ]

1 голос
/ 10 июня 2010

Как сказал @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, чтобы сотрудники работали более обычным образом.

Делись и наслаждайся.

1 голос
/ 10 июня 2010

У вас есть три таблицы и только одно условие соединения;вам нужно соединение между сотрудником и одобрения.Без этого вы получаете перекрестное произведение или декартово объединение между этими таблицами.

С N таблицами (N> 0) вам необходимо как минимум условия объединения J = N-1.У вас N = 3 таблицы, но J = 1 условия соединения - что слишком мало.(Существуют различные причины, по которым вам может понадобиться J> N - 1, но основная причина заключается в том, что вам нужно объединить два столбца между двумя таблицами. Если вы считаете каждое условие 'A.Col1 = B.Col2' как отдельное условие соединения, тогда вам нужно J> N-1, если вы посчитаете пару условий 'A.Col1 = B.Col2 AND A.Col3 = B.Col4' как одно условие соединения, то вам все равно нужен только J = N-1условия.)

В идеале вы также должны отойти от архаичной нестандартной нотации внешнего соединения, используя '(+)', и использовать стандартные SQL-соединения.


Нотацияэто вторичная проблема.Каждая строка в Employee объединяется с каждой строкой в ​​одобрении, а затем этот перекрестный продукт соединяется с Helicopter_type.Это (почти наверняка) не тот запрос, который требуется.

Возможно, вам потребуется добавить несколько вариантов этого в предложение WHERE:

AND E.EMP_NBR = ED.EMP_NBR

(где фактический столбец в индоссаменте(ED) таблица не отображается в запросе, поэтому «ED.EMP_NBR» является предположением).

Среди других эффектов, если в базе данных есть пилоты вертолетов, то каждая запись сотрудника объединяется сподтверждение пилота иногда, и порядок сортировки означает, что эти записи будут показаны перед бесчисленным количеством записей, которые показывают, что пилоты не имеют одобрений вертолетов, и что не пилоты не имеют записей вертолетов и т. д...

0 голосов
/ 10 июня 2010

Проверьте, имели ли HT_NAME и END_HRS_FLOWN нулевые значения или нет для ожидаемых вами строк N / A или 0

Редактировать 1

В Oracle функция NVL позволяет подставлять значение, когда встречается нулевое значение.

Синтаксис для функции NVL:

NVL( string1, replace_with )

string1 - строка для проверки на нулевое значение.

replace_with - это значение, возвращаемое, если строка1 равна нулю.

Если значение не равно нулю , будет возвращено то же значение

...