开发者

Oracle SQL case when for ordering

I have to sort out my data by some column, such that some specific value appears first. So for a query like this ...

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

... I have based it on case when, but what bothers me is three nested selects I have now:

  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

Performance-wise I think it shouldn't be a problem, but it looks kind of a spaghetti... Is there any way to开发者_开发问答 put case-when into the where clause?


You are querying the tasks table twice. This is not needed and will make your query run slowly. Your query can be combined into a simple query like so:

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;

Then either just retrieve the first row or add the rownum part in an outer query.


user 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;


If taskid is the primary key of tasks you don't need the self-join (outer 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜