2010-03-11 97 views
2

我不得不按一些列来排序我的数据,这样一些特定的值首先出现。因此,对于这样的查询...Oracle SQL的情况下,为了排序

SELECT rtrim(taskid) into v_taskid FROM tasks 
    where 
    /* some where clausers */ 
    and rownum = 1 

...我已经根据它case when,但什么困扰我的是三个嵌套选择我现在有:

SELECT rtrim(taskid) into v_taskid FROM tasks where taskid in (
    select taskid from (
     select taskid, 
     case when taskuser like '%myuser%' 
     then 0 
      else 100 
     end as ordervalue 
     FROM tasks 
     where  
      /* some where clausers */ 
     order by ordervalue 
     ) 
    )  
    and rownum = 1 

性能方面,我认为它不应该是一个问题,但它看起来像一种意大利面条...有什么办法可以将case-when纳入where条款吗?

回答

3

要查询的tasks表的两倍。这不是必需的,并且会使您的查询运行缓慢。您的查询可以组合成一个简单的查询,像这样:

SELECT rtrim(taskid) into v_taskid 
FROM (
    SELECT taskid 
    FROM tasks 
    WHERE /* some where clauses */ 
    ORDER BY case when taskuser like '%myuser%' then 0 else 100 end 
) 
WHERE rownum = 1; 

然后要么只是检索的第一行或在外部查询添加ROWNUM部分。

1

用户row_number() over (...)

select 
    taskid 
from (
    select 
    taskid, 
    row_number() over (
     order by 
     case when taskuser like '%myuser%' then 0 
              else 100 
     end 
    ) r 
    from 
    tasks 
    WHERE 
    /* some where clausers */ 
) 
where 
    r = 1; 
+0

此处不需要分析查询,并会影响性能。 – 2010-03-11 12:56:49

1

如果taskidtasks主键你不需要自联接(外部SELECT):

SELECT rtrim(taskid) 
    FROM (SELECT taskid 
      FROM tasks 
      /* where clause */ 
      ORDER BY CASE 
         WHEN taskuser LIKE '%myuser%' THEN 
         0 
         ELSE 
         100 
        END) 
WHERE ROWNUM = 1