代码之家  ›  专栏  ›  技术社区  ›  Caius Jard

分析函数是否可以用来寻找以其他单词开头的单词子集?

  •  0
  • Caius Jard  · 技术社区  · 6 年前

    不是重复的:我的另一个标题相同的问题针对MySQL,这个问题针对oracle

    基本上在以下列表中(2列,varchar,int):

    'APP',3
    'APPLE',2
    'APPLICATION',7
    'BOW',2
    'BRA',6
    'BRAVE',5
    'BRAVERY',3
    'CANED',2
    'CANES',4
    

    我想去掉APPLE,APPLICATION,BRAVE和BRAVERY,但是把它们的数字加在词根上,这样APP的分数是3+2+7,BRA的分数是6+5+3

    'APP',12
    'BRA',14
    'BOW',2
    'CANED',2
    'CANES',4
    

    我觉得可以通过创建一个列来实现,每次当前行单词不以任何前一行单词开头,并且当前行单词不长于前一行单词时,该列都会递增,然后将其用作分区。。这是我一直坚持的与任何前一行字位-本质上是苹果和应用程序都以应用程序开始,但应用程序并不是以苹果开始的(而勇敢是以勇敢开始的),所以将前一行与当前行进行比较是行不通的

    我已经可以在MySQL和SQLS中使用连接和变量,在Oracle中使用连接(将表连接回自身几次)。。我想知道是否有一个一键式的方式,避免所有使用加入

    2 回复  |  直到 6 年前
        1
  •  1
  •   mathguy    6 年前

    在Oracle中,您可以使用 MATCH_RECOGNIZE 条款。关键是 匹配\u识别 需要Oracle 12.1或更高版本。

    匹配\u识别 r )或“扩展”( e )在一个关卡中,同时能够在同一关卡中识别一个“组”(一个 ,在技术术语中)结束,下一个开始-并且对每个匹配的值求和,仍然在同一过程中。

    我不认为你能简单地用解析函数做同样的事情。

    :对于较旧版本的Oracle,可以使用 MODEL 条款(也是Oracle专有的)。这需要Oracle 10.1或更高版本。答案底部提供的解决方案(在 解决方案)。

    with
      simulated_data(word, val) as (
        select 'APP'        , 3 from dual union all
        select 'APPLE'      , 2 from dual union all
        select 'APPLICATION', 7 from dual union all
        select 'BOW'        , 2 from dual union all
        select 'BRA'        , 6 from dual union all
        select 'BRAVE'      , 5 from dual union all
        select 'BRAVERY'    , 3 from dual union all
        select 'CANED'      , 2 from dual union all
        select 'CANES'      , 4 from dual
      )
    select root_word, total_value
    from   simulated_data
    match_recognize(
      order by word
      measures r.word   as root_word,
               sum(val) as total_value
      pattern  ( r e* )
      define   e as e.word like r.word || '%'
    )
    ;
    
    ROOT_WORD   TOTAL_VALUE
    ----------- -----------
    APP                  12
    BOW                   2
    BRA                  14
    CANED                 2
    CANES                 4
    

    型号

    with
      simulated_data(word, val) as (
        select 'APP'        , 3 from dual union all
        select 'APPLE'      , 2 from dual union all
        select 'APPLICATION', 7 from dual union all
        select 'BOW'        , 2 from dual union all
        select 'BRA'        , 6 from dual union all
        select 'BRAVE'      , 5 from dual union all
        select 'BRAVERY'    , 3 from dual union all
        select 'CANED'      , 2 from dual union all
        select 'CANES'      , 4 from dual
      )
    select rw as root_word, tv as total_value
    from   (
             select rw, tv, fl
             from   simulated_data
             model
               dimension by (row_number() over (order by word) as rn)
               measures     (word, val, rpad('x', 4000, 'x') as rw, 0 as tv, 0 as fl)
               rules        (
                 rw[any] = case instr(word[cv()], rw[cv()-1]) 
                                when 1 then rw[cv()-1] else word[cv()] end,
                 tv[any] = case rw[cv()] when rw[cv()-1] 
                                then tv[cv()-1] + val[cv()] else val[cv()] end,
                 fl[any] = case rw[cv()] when rw[cv()+1] 
                                then 0 else 1 end
               )
           )
    where  fl = 1
    ;
    
        2
  •  0
  •   D-Shih    6 年前

    你可以试着写一个 CASE WEHN LIKE 在里面 GROUP BY

    查询1 :

    SELECT 
    (CASE
        WHEN name LIKE 'APP%' THEN 'APP'
        WHEN name LIKE 'BRA%' THEN 'BRA'
        ELSE name
    END) name,SUM(amount) 
    FROM T
    GROUP BY 
    CASE
        WHEN name LIKE 'APP%' THEN 'APP'
        WHEN name LIKE 'BRA%' THEN 'BRA'
        ELSE name
    END
    

    如果你不想用 凯斯韦恩 就像 分组依据 .

    mapper 表中的关键字名称,因为您需要告诉程序哪个是您的expect关键字。

    CREATE TABLE T(name varchar(50),amount int);
    
    insert into t values ('APP',3);
    insert into t values ('APPLE',2);
    insert into t values ('APPLICATION',7);
    insert into t values ('BOW',2);
    insert into t values ('BRA',6);
    insert into t values ('BRAVE',5);
    insert into t values ('BRAVERY',3);
    insert into t values ('CANED',2);
    insert into t values ('CANES',4);
    
    CREATE TABLE maaper(
        name VARCHAR(50)
    );
    
    INSERT INTO maaper VALUES ('APP');
    INSERT INTO maaper VALUES ('BRA');
    

    查询1 :

    SELECT coalesce(t2.name,t1.name) name,sum(AMOUNT)
    FROM T t1 LEFT JOIN (
        SELECT name 
        FROM maaper
    ) t2 ON t1.name like  t2.name || '%'
    group by coalesce(t2.name,t1.name)
    

    Results :

    |  NAME | SUM(AMOUNT) |
    |-------|-------------|
    |   BRA |          14 |
    | CANED |           2 |
    |   APP |          12 |
    | CANES |           4 |
    |   BOW |           2 |