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

发布于 2024-09-05 14:50:24 字数 610 浏览 6 评论 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。它不起作用 - 尽管我已经尝试了多种方法来修复它。

I'm needing to select first and last name in a table which is working fine in the following SQL, but the part that isn't working is the NVL function. The file should show all pilots at a company that fly helicopters and IF they don't have a licence the field HT_NAME should come up as 'N/A' and the field for end hours flown should be 0. I've put NVL function in as my text details but it still isn't working. Have i made a syntax error? Help would be appreciated.

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;

should make employees who are not pilots appear with a N/A under heli type and 0 under hours flown. It isn't working - even though I have tried multiple things to repair it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月静好 2024-09-12 14:50:24

正如@Jonathan 所说,您需要在 WHERE 子句中添加一些内容来告诉数据库如何将 EMPLOYEE 与 ENDORSMENT 相匹配。出于讨论目的,我们将在两者上使用 EMP_NBR 字段,但您需要更改查询以使用正确的字段。我们还需要知道哪个字段可以告诉您员工是否拥有有效的许可证。我猜它是 ENDORSMENT 表中的内容 - 为了讨论的目的,我们将其称为 ENDORSMENT.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 子句,以便以更正常的方式对员工进行排序。

分享并享受。

As @Jonathan said, you need to add something to the WHERE clause to tell the database how to match up EMPLOYEE with ENDORSEMENT. For purposes of discussion we'll use the EMP_NBR field on both, but you'll need to change the query around to use the field that's correct. We also need to know what field tells you if an employee has a valid license. I'm guessing it's something on the ENDORSEMENT table - let's call it ENDORSEMENT.LICENSE_TYPE for purposes of discussion. Once you know that you can use the NVL2 function to alter the values returned by the query appropriately, as follows:

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;

I also changed the ORDER BY clause to get the employees ordered in a more normal manner.

Share and enjoy.

苦笑流年记忆 2024-09-12 14:50:24

你有三张表,只有一个连接条件;您需要在员工和认可之间加入。如果没有它,您将在这些表之间获得叉积或笛卡尔连接。

对于 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

其中 Endorsement (ED) 表中的实际列未显示在查询中,因此“ED.EMP_NBR”是猜测)。

除其他影响外,如果数据库中有任何直升机飞行员,那么每条员工记录有时都会与飞行员的认可相结合,并且排序顺序意味着这些记录将显示在无数记录之前,这些记录表明飞行员没有直升机认可,非飞行员没有直升机记录,等等......

You have three tables and only one join condition; you need a join between Employee and Endorsement. Without that, you are getting a cross-product or Cartesian join between those tables.

With N tables (N > 0), you need J = N-1 join conditions at minimum. You have N = 3 tables, but J = 1 join conditions - which is too few. (There are various reasons why you might need J > N - 1, but the main one is because you need to join two columns between two tables. If you count each 'A.Col1 = B.Col2' condition as a separate join condition, then you need J > N-1; if you count the pair of conditions 'A.Col1 = B.Col2 AND A.Col3 = B.Col4' as a single join condition, then you still only need J = N-1 conditions. )

Ideally, you should also move away from the archaic, non-standard outer join notation using '(+)' and use the standard SQL joins.


The notation is a secondary issue. Every row in Employee is being joined with every row in Endorsement - and then that cross-product is being outer-joined with Helicopter_type. This is (almost certainly) not the query that is required.

You probably need to add some variation of this to the WHERE clause:

AND E.EMP_NBR = ED.EMP_NBR

(where the actual column in the Endorsement (ED) table is not shown in the query, so 'ED.EMP_NBR' is a guess).

Amongst other effects, if there are any helicopter pilots in the database, then every employee record is being joined with the endorsement for a pilot some of the time, and the sort order means that those records will be shown before the myriad records which show that the pilots don't have helicopter endorsements and that non-pilots don't have helicopter records, etc...

一江春梦 2024-09-12 14:50:24

检查您期望的行的 HT_NAME 和 END_HRS_FLOWN 是否具有空值 N/A 或 0

编辑 1

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

NVL 函数的语法为:

NVL( string1, replace_with )

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

replace_with 是 string1 为 null 时返回的值。

如果该值不为空,它将返回相同的值

Check whether HT_NAME and END_HRS_FLOWN were having null values or not for the rows you expect N/A or 0

Edit 1

In Oracle, the NVL function lets you substitute a value when a null value is encountered.

The syntax for the NVL function is:

NVL( string1, replace_with )

string1 is the string to test for a null value.

replace_with is the value returned if string1 is null.

If the value is not null, it will return same value

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文