嗨专家我需要实现一个PL / SQL函数HIGHTRIP(LICENSENUM),它找到由驾驶执照号码识别的驾驶员执行的最长行程(表DRIVER中的LNUM属性和函数中的参数LICENSENUM参数)。我需要显示不执行任何旅行的司机。
这是我到目前为止所做的。
SELECT DRIVER.LNUM AS LICENSE_NO,
COUNT(TRIP.TNUM) AS TOTAL_NO_TRIPS
FROM DRIVER
LEFT OUTER JOIN TRIP
ON DRIVER.LNUM = TRIP.LNUM
INNER JOIN TRIPLEG
ON TRIP.TNUM = TRIPLEG.TNUM
GROUP BY DRIVER.LNUM
ORDER BY DRIVER.LNUM
然而,上述声明并未显示未进行任何旅行的abt司机。
不确定如何将语句转换为满足上述条件的函数。
答案 0 :(得分:0)
好吧,我建议你拆分你的需求,从最简单的部分开始构建,而不是先尝试编写整个查询。您的查询返回给定驱动程序的TRIPLEG
表中的行数,这似乎不符合您的要求。我还建议您查看PL/SQL documentation,尤其是CREATE FUNCTION syntax和examples。
例如,我会在以下子任务中解决您的问题:
一名司机的行程长度。如果我错了,请纠正我,但如果我要列出所有相关长度的行程,那就是:
SELECT t.tnum, COUNT(*) length
FROM trip t
JOIN tripleg tl ON t.tnum = tl.tnum
WHERE t.lnum = :LNUM
GROUP BY t.tnum
选择这些旅程中最长的一次:
SELECT tnum
FROM (SELECT t.tnum, COUNT(*) length
FROM trip t
JOIN tripleg tl ON t.tnum = tl.tnum
WHERE t.lnum = :LNUM
GROUP BY t.tnum
ORDER BY COUNT(*) DESC)
WHERE rownum = 1
编写一个返回此结果的函数:
CREATE OR REPLACE FUNCTION hightrip (p_lnum trip.lnum%type)
RETURN trip.tnum%type IS
l_result trip.tnum%type;
BEGIN
SELECT tnum
INTO l_result
FROM (SELECT t.tnum, COUNT(*) length
FROM trip t
JOIN tripleg tl ON t.tnum = tl.tnum
WHERE t.lnum = p_lnum
GROUP BY t.tnum
ORDER BY COUNT(*) DESC)
WHERE rownum = 1;
RETURN l_result;
END hightrip ;
在SELECT上使用此功能:
SELECT d.*, hightrip(d.lnum)
FROM driver d;
HIGHTRIP
函数在从NO_DATA_FOUND
调用没有行程的驱动程序时会产生PL/SQL
异常。但是,这样的异常在SQL中被视为NULL
,因此您可以按原样使用上述查询。
答案 1 :(得分:0)
“但是上面的陈述没有显示没有的abt司机 任何旅行。“
没有任何旅行的司机将不会在TRIPLEG中有任何记录。因此,该表上的INNER JOIN将覆盖DRIVER和TRIP之间的OUTER JOIN,从而过滤掉留在家中的司机。
你需要做的是这样的事情:
SELECT DRIVER.LNUM AS LICENSE_NO,
TRIPS.TOTAL_NO_TRIPS
FROM DRIVER
LEFT OUTER JOIN ( SELECT TRIP.LNUM,
COUNT(TRIP.TNUM) AS TOTAL_NO_TRIPS
FROM TRIP
INNER JOIN TRIPLEG
ON TRIP.TNUM = TRIPLEG.TNUM
GROUP BY TRIP.LNUM ) TRIPS
ON DRIVER.LNUM = TRIPS.LNUM
ORDER BY DRIVER.LNUM
/
您还需要了解如何在代码中使用小写。完全用大写字母编写的程序与COBOL一起发布,因为它们太难阅读了。