我有一张表说STAFF如下:
STAFF_NAME
============
ALEX
BERNARD
CARL
DOMINIC
EMMA
现在,我想用单个参数编写一个存储函数。例如。 GET_NEXT_STAFF(CURRENT_STAFF).
输入和输出应该是:
Input | Output
=====================
NULL | ALEX
ALEX | BERNARD
BERNARD | CARL
EMMA | ALEX (Start from the beginning of the table again)
我知道如何使用PL / SQL处理这个问题,但是用一个select语句可以处理这个问题吗?
答案 0 :(得分:2)
在下面的解决方案中,我假设行按名称按字母顺序排序。它们可能由同一个表中的另一列(例如按雇用日期,或通过工资等等 - 按顺序排序) - 然后该列的名称应该在两个分析的ORDER BY子句中使用功能
输入名称作为绑定变量:input_staff_name
传入。该解决方案使用纯SQL,不需要函数(PL / SQL),但如果必须将其转换为函数,则可以轻松地对其进行调整。
修改:在我的原始回答中,当输入为null
时,我错过了所需的行为。最后一行代码(不包括分号)负责处理。如当前所写,当输入为null
时,查询返回ALEX(或通常是表中的第一个值),并且当输入不为空且不在表中时,它不返回任何行。如果要求是在输入为null
或在表格中找不到时返回名字,则可以通过从最后一行删除and :input_staff_name is null
来轻松容纳它。
with
tbl ( staff_name ) as (
select 'ALEX' from dual union all
select 'BERNARD' from dual union all
select 'CARL' from dual union all
select 'DOMINIC' from dual union all
select 'EMMA' from dual
),
prep ( staff_name, next_name, first_name ) as (
select staff_name,
lead(staff_name) over (order by staff_name),
first_value (staff_name) over (order by staff_name)
from tbl
)
select nvl(next_name, first_name) as next_staff_name
from prep
where staff_name = :input_staff_name
or (next_name is null and :input_staff_name is null)
;
答案 1 :(得分:0)
根据@mathguy的回答,我做了一些似乎有效的改动。我添加了以下
UNION ALL
SELECT NULL
FROM DUAL
和
WHERE NVL (staff_name, 'X') = NVL (NULL, 'X');
完整代码
WITH tbl (staff_name) AS
(SELECT 'ALEX' FROM DUAL
UNION ALL
SELECT 'BERNARD' FROM DUAL
UNION ALL
SELECT 'CARL' FROM DUAL
UNION ALL
SELECT 'DOMINIC' FROM DUAL
UNION ALL
SELECT 'EMMA' FROM DUAL
UNION ALL
SELECT NULL
FROM DUAL),
prep (staff_name,
next_name,
first_name,
last_name) AS
(SELECT staff_name,
LEAD (staff_name) OVER (ORDER BY staff_name),
FIRST_VALUE (staff_name) OVER (ORDER BY staff_name),
LAG (staff_name) OVER (ORDER BY staff_name)
FROM tbl)
SELECT NVL (next_name, first_name) AS next_staff_name
FROM prep
WHERE NVL (staff_name, 'X') = NVL (:input_staff_name, 'X');