我有一个函数返回一个值并显示轨道之间的相似性,我希望返回的结果按此返回值排序,但我无法弄清楚如何做到这一点,这里是我已经有的尝试:
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;
/
没有给出错误,列表只是未分类,是不是可以按函数返回的值排序?如果是这样,我怎么做到这样的事情?或者我只是在做一些可怕的错误?
任何帮助将不胜感激
答案 0 :(得分:1)
为了(过度)优化,我会避免按功能排序,如果我可以避免它;特别是查询其他表的人。如果您要查询表格,则应该能够将该部分添加到当前查询中,这样您就可以正常使用它。
但是,让我们来看看你的功能:
使用DBMS_OUTPUT
除了调试之外没有任何意义,除非你将会在那里查看每个输出的确切内容运行该功能的时间;你可以删除这些行。
以下内容仅用于DBMS_OUTPUT
,因此是不必要的SELECT,可以删除:
select * into chosenTrack from tracks where track_id = frstTrack;
您正在从表TRACKS中随机选择10行;为什么呢?
FOR res IN (select * from tracks WHERE ROWNUM <= 10)LOOP
您的ORDER BY,order by sim
由不存在的列排序,因为列SIM未在SELECT范围内声明
您的ORDER BY要求至少类似,因为默认排序顺序是升序的(这可能是正确的,但似乎错了?)
您的功能不是功能,它是一个程序(没有OUT参数的程序)。
您的SELECT INTO正在尝试将多行放入单行变量中。
假设你的&#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 */