按oracle中的函数返回的值排序

时间:2014-04-17 11:55:03

标签: oracle plsql plsqldeveloper

我有一个函数返回一个值并显示轨道之间的相似性,我希望返回的结果按此返回值排序,但我无法弄清楚如何做到这一点,这里是我已经有的尝试:

CREATE OR REPLACE PROCEDURE proc_list_similar_tracks(frstTrack IN tracks.track_id%TYPE)
AS
  sim number;
  res tracks%rowtype;
  chosenTrack tracks%rowtype;

BEGIN
select * into chosenTrack from tracks where track_id = frstTrack;
dbms_output.put_line('similarity between');
FOR res IN (select * from tracks WHERE ROWNUM <= 10)LOOP
    SELECT * INTO sim FROM ( SELECT func_similarity(frstTrack, res.track_id)from dual order by sim)  order by sim; //that's where i am getting the value and where i am trying to order

    dbms_output.put_line( chosenTrack.track_name || '(' ||frstTrack|| ') and ' ||     res.track_name || '(' ||res.track_id|| ') ---->' ||  sim);
END LOOP;
END proc_list_similar_tracks;

/
declare
begin
proc_list_similar_tracks(437830);
end;
/

没有给出错误,列表只是未分类,是不是可以按函数返回的值排序?如果是这样,我怎么做到这样的事情?或者我只是在做一些可怕的错误?

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:1)

为了(过度)优化,我会避免按功能排序,如果我可以避免它;特别是查询其他表的人。如果您要查询表格,则应该能够将该部分添加到当前查询中,这样您就可以正常使用它。

但是,让我们来看看你的功能:

  1. 使用DBMS_OUTPUT除了调试之外没有任何意义,除非你将会在那里查看每个输出的确切内容运行该功能的时间;你可以删除这些行。

  2. 以下内容仅用于DBMS_OUTPUT,因此是不必要的SELECT,可以删除:

    select * into chosenTrack from tracks where track_id = frstTrack;
    
  3. 您正在从表TRACKS中随机选择10行;为什么呢?

    FOR res IN (select * from tracks WHERE ROWNUM <= 10)LOOP
    
  4. 您的ORDER BY,order by sim由不存在的列排序,因为列SIM未在SELECT范围内声明

  5. 您的ORDER BY要求至少类似,因为默认排序顺序是升序的(这可能是正确的,但似乎错了?)

  6. 您的功能不是功能,它是一个程序(没有OUT参数的程序)。

  7. 您的SELECT INTO正在尝试将多行放入单行变量中。

  8. 假设你的&#34;功能&#34;被更改以提供参数与随机10个TRACK_ID之间的最大相似度,它可能如下所示:

    create or replace function list_similar_tracks (
          frstTrack in tracks.track_id%type 
          ) return number is
    
       sim number;
    
    begin
    
        select max(func_similarity(frstTrack, track_id)) into sim
          from tracks
         where rownum <= 10
               ;
    
    
       return sim;
    
    end list_similar_tracks;
    /
    

    然而,该功能的名称似乎排除了这是您实际尝试做的事情。


    从您的评论中,您的问题实际上是:

    我有以下代码;如何打印前10个功能结果?当前结果未经排序返回。

    declare
       sim number;
    begin
    
       for res in ( select * from tracks ) loop
          select * into sim 
            from ( select func_similarity(var1, var2) 
                     from dual 
                    order by sim
                          )  
           order by sim;
       end loop;
    end;
    /
    

    上述问题首先是您通过变量 sim进行排序,在第一个实例中为NULL,但之后会发生变化。但是,从DUAL中选择只是一个行,这意味着您可以通过单行随机排序。这让我们回到最顶层 - 尽可能使用SQL。

    在这种情况下,您只需从表TRACKS中选择SELECT,然后按功能结果排序。为此,您需要为函数结果创建的列赋予别名(或按Emmanuel's answer中所述的位置参数排序)。

    例如:

    select func_similarity(var1, var2) as function_result
      from dual 
    

    将这些代码组合在一起:

    begin
    
       for res in ( select *
                      from ( select func_similarity(variable, track_id) as f
                               from tracks
                              order by f desc
                                    )
                     where rownum <= 10 ) loop
          -- do something
       end loop;
    
    end;
    /
    

答案 1 :(得分:0)

你有一个使用函数的查询,比如说:

select t.field1, t.field2, ..., function1(t.field1), ...
from table1 t
where ...

Oracle支持带有列索引的order by子句,即如果函数返回的字段是select中的第n个字段(此处field1位于位置1,field2就位2),你只需要添加:

order by n

例如:

select t.field1, function1(t.field1) c2
from table1 t
where ...
order by 2 /* 2 being the index of the column computed by the function */
相关问题