在SQL中使用NVL函数,请帮忙!

时间:2010-06-10 08:00:41

标签: sql database oracle nvl

我需要在一个表中选择名字和名字,这个名称在以下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小时。它没有用 - 即使我已经尝试过多种方法来修复它。

3 个答案:

答案 0 :(得分:1)

您有三个表,只有一个连接条件;您需要在员工和背书之间加入。没有它,您将在这些表之间获得跨产品或笛卡尔联接。

对于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中的每一行都与Endorsement中的每一行相连接 - 然后该交叉产品与Helicopter_type外部连接在一起。这(几乎可以肯定)不是所需的查询。

您可能需要在WHERE子句中添加一些变体:

AND E.EMP_NBR = ED.EMP_NBR

(在背书(ED)表中的实际列未显示在查询中,因此'ED.EMP_NBR'是猜测)。

在其他影响中,如果数据库中有任何直升机飞行员,那么每个员工记录都会在某些时候加入飞行员的认可,排序顺序意味着这些记录将显示在无数记录之前这表明飞行员没有直升机代言,非飞行员没有直升机记录等......

答案 1 :(得分: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子句,以便以更正常的方式订购员工。

分享并享受。

答案 2 :(得分:0)

检查HT_NAME和END_HRS_FLOWN对于您期望的行N / A或0

是否具有空值

修改1

在Oracle中,NVL函数允许您在遇到空值时替换值。

NVL功能的语法是:

NVL( string1, replace_with )

string1 是要测试空值的字符串。

replace_with 是string1为null时返回的值。

如果值为非空,则返回相同的值