sql中的条件order by子句

时间:2013-01-30 06:03:27

标签: sql oracle

我有一个查询应该根据列值在asc或desc中排序结果。

e.g。

如果类型管理员的员工通过join_date,bith_date ASC存在那么订单 否则,如果员工是开发人员,那么可以通过join_date,birth_date DESC订购。

我想实现类似下面的内容,但无法实现。

ORDER BY CASE WHEN employee_type = 'm'  
              THEN joining_date, birth_date ASC;
              WHEN employee_type = 'd' 
              THEN joining_date, birth_date  DESC; 

4 个答案:

答案 0 :(得分:15)

经过一番研究后我得到了答案。

我们可以在where子句中有条件地添加多个列,如下所示:

ORDER BY DECODE(employee_type, 'm', joining_date, birth_date, salary) ASC,
         DECODE(employee_type, 'd', joining_date, birth_date, salary) DESC

这将根据employee_type对结果进行排序。

答案 1 :(得分:3)

我怀疑你想要这样的东西:

ORDER BY 
    employee_type DESC             -- first all the managers, then the developers
                                   -- and in every one of these two groups
  , joining_date                   -- first order by joining date
  , CASE WHEN employee_type = 'm'  -- and then either by
        THEN birth_date            -- birth date ascending for managers
        ELSE NULL
    END                            -- or
  , birth_date DESC ;              -- birth date descending for the rest (devs)

答案 2 :(得分:0)

问题是指定的有点差。

  

根据列值将结果排序为asc或desc。

列需要很多值(因为有多行)。

现在,order by子句使用表达式并对其进行排序。 那个表达式应该是morphotropic(;))

因此,假设标准的oracle员工架构,经理是:

select * 
from emp e
where exists (select emp_id from emp where e.id=emp.mgr_id)

变通方法查询可能是:

Select e.id, e.name, e.birth_date,
  case 
  when   (select count(*)  
          from emp e 
          where exists (select emp_id from  emp where e.id=emp.mgr_id)
          ) --existence of manager
    > 0 then birth_date - to_date('1-Jan-1000','dd-mon-yyyy')
    else to_date('1-Jan-1000','dd-mon-yyyy') - birth_date
   end as tricky_expression
from emp A
order by 4;

该exexpresion是case;使用常量(决定有经理的子查询),它将值从正变为负,即更改顺序方向。

更新,其中包含评论中的详细信息:

select id, name, birth_date emp_type
from (
    Select id, name, birth_date, emp_type,
        case  when   cnt_mgr > 0 then birth_date - to_date('1-Jan-1000','dd-mon-yyyy')
          else to_date('1-Jan-1000','dd-mon-yyyy') - birth_date
        end as tricky_expression
    from(
        Select e.id, e.name, e.birth_date, emp_type,
           count(case when emp_type='M' then 1 else 0 end) over() as mgr_count
        from emp A
        where your_conditions
        )
     order by tricky_expression
)
where rownum=1;

答案 3 :(得分:0)

如果公司中有经理,这个查询会返回最老的经理,否则 - 最年轻的经理。

select 
  id, name, birth_date, emp_type
from emp
where 
  id = (select 
           max(id) keep (dense_rank first order by 
             decode(emp_type, 'M', 1, 'D', 2),
             joining_date,
             decode(emp_type, 'M', 1, 'D', -1) * (birth_date - to_date('3000','yyyy')))
        from emp)