idk如何提出正确的问题,但在这里,
鉴于我有这个my_table。我需要在每个INFO START和INFO END之间只显示一个速率,如果我没有,则需要NULL。
RATE:
1. BEST
2. BETTER
3. GOOD
所以,如果我有两个更好的'并且“好”'在INFO START和INFO END范围内,我将显示更好的'而不是“好”。而且“最好的'如果是最好的'在那里。
MY_TABLE
RNUM VAL
1 game of thrones
2 electric fan
3 INFO START
4 name: polo
5 white
6 better
7 slacks
8 tv
9 good
10 INFO END
11 keyboard
12 guitar
13 INFO START
14 name: mirror
15 best
16 good
17 better
18 INFO END
19 INFO END
20 INFO END
21 bag
22 INFO START
23 name: monitor
24 music
25 best
26 telephone
27 INFO END
28 INFO END
29 ADFASD
我的预期输出
NAME RATE
POLO BETTER
MIRROR BEST
MONITOR BEST
到目前为止,我可以获得INFO START和INFO END的范围,我应该找到名称和费率。
我的代码;
declare
v_rnum varchar2(50);
v_val varchar2(50);
v_r_end varchar2(50);
begin
for i in (with t1 as (select rownum rnum_new, a.*
from (select *
from samp2
where val like '%INFO START%'
union
select *
from samp2
where val like '%INFO END%')A
ORDER BY RNUM ASC)
select a.*, b.rnum rnum_end
from t1 a inner join t1 b
on a.rnum_new + 1 = b.rnum_new
where a.val like '%INFO START%')
loop
dbms_output.put_line(i.rnum ||' ' || i.val|| ' '|| i.rnum_end);
end loop;
end;
继承其输出(我到目前为止使用了dbms_output进行测试但是我稍后会将它插入到表中 我可以得到正确的费率)
3 INFO START 10
13 INFO START 18
22 INFO START 27
所以任何想法如何显示费率?我想我可以在这里使用rank()作为我的费率,但我不熟悉如何在这种情况下使用它。你有任何建议或提示怎么做? rank()或任何可以解决此问题的样式。谢谢!希望你能理解我的英语。
这是我使用db-fiddle.com
的小提琴CREATE TABLE samp (
val varchar(50)
);
INSERT INTO samp (val) VALUES ('game of thrones');
INSERT INTO samp (val) VALUES ('electric fan');
INSERT INTO samp (val) VALUES
('INFO START');
INSERTINSERT INTO samp (val) VALUES
('Name: Polo');
INSERT INTO samp (val) VALUES
('White');
INSERT INTO samp (val) VALUES
('Better');
INSERT INTO samp (val) VALUES
('Slacks');
INSERT INTO samp (val) VALUES
('Tv');
INSERT INTO samp (val) VALUES
('Good');
INSERT INTO samp (val) VALUES
('INFO END');
INSERT INTO samp (val) VALUES
('keyboard');
INSERT INTO samp (val) VALUES
('Guitar');
INSERT INTO samp (val) VALUES
('INFO START');
INSERT INTO samp (val) VALUES
('Name: Mirror');
INSERT INTO samp (val) VALUES
('Best');
INSERT INTO samp (val) VALUES
('Good');
INSERT INTO samp (val) VALUES
('Better');
INSERT INTO samp (val) VALUES
('INFO END');
INSERT INTO samp (val) VALUES
('INFO END');
INSERT INTO samp (val) VALUES
('INFO END');
INSERT INTO samp (val) VALUES
('Bag');
INSERT INTO samp (val) VALUES
('INFO START');
INSERT INTO samp (val) VALUES
('Name: Monitor');
INSERT INTO samp (val) VALUES
('music');
INSERT INTO samp (val) VALUES
('best');
INSERT INTO samp (val) VALUES
('telephone');
INSERT INTO samp (val) VALUES
('INFO END');
INSERT INTO samp (val) VALUES
('INFO END');
INSERT INTO samp (val) VALUES
('ADFASD')
答案 0 :(得分:0)
您可以使用此代码。这比我想象的要复杂得多。此处使用的表格为test_samp
。由于您的表没有用于标识插入序列的列,因此我使用了ROWID
。但是,它并非万无一失。您需要添加另一列来跟踪order by
循环内该列的序列和FOR
。
SET SERVEROUTPUT ON;
DECLARE
v_name test_samp.val%TYPE;
v_n NUMBER := 0;
v_rate VARCHAR2 (10);
v_oper NUMBER := 0;
BEGIN
DBMS_OUTPUT.PUT_LINE ('NAME' || ' ' || 'RATE');
FOR item IN ( SELECT *
FROM test_samp
ORDER BY ROWID)
LOOP
IF item.val = 'INFO START'
THEN
v_oper := 1;
END IF;
IF v_oper = 1 AND item.val LIKE 'Name: %'
THEN
v_name :=
REGEXP_SUBSTR (item.val,
'Name: (.+)$',
1,
1,
'i',
1);
END IF;
IF v_oper = 1 AND UPPER (item.val) IN ('GOOD', 'BETTER', 'BEST')
THEN
WITH rating_logic
AS (SELECT 1 n, 'GOOD' rate FROM DUAL
UNION ALL
SELECT 2 n, 'BETTER' rate FROM DUAL
UNION ALL
SELECT 3 n, 'BEST' rate FROM DUAL)
SELECT GREATEST (v_n, n)
INTO v_n
FROM rating_logic r
WHERE UPPER(r.rate) = UPPER(item.val);
END IF;
IF item.val = 'INFO END' AND v_oper = 1
THEN
WITH rating_logic
AS (SELECT 1 n, 'GOOD' rate FROM DUAL
UNION ALL
SELECT 2 n, 'BETTER' rate FROM DUAL
UNION ALL
SELECT 3 n, 'BEST' rate FROM DUAL)
SELECT rate
INTO v_rate
FROM rating_logic r
WHERE r.n = v_n;
DBMS_OUTPUT.PUT_LINE (v_name || ' ' || v_rate);
v_oper := 0;
v_n := 0;
END IF;
END LOOP;
END;
/