如何显示某些排名的单词?

时间:2017-09-28 21:14:15

标签: oracle plsql

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')

1 个答案:

答案 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;
/