2014-09-25 451 views
4

我有一个查询,我想根据条件进行两种排序。Oracle按不同条件排序

例如,如果一个字段为NULL,我需要作出一个命令,如果它不是,我不得不做另一个命令。我怎么能做到这一点?

select * 
    from table_1 t 
    order by (if t.field1 is null then 
        order by t.field2 DESC, field3 ASC 
      else 
        order by t.field4 ASC, field5 DESC) 

这是一个示例代码:我想使不同的顺序(ASC/DESC和不同列)的基础上,FIELD1

的值

有条件

ID FIELD1 FIELD2 FIELD3 FIELD4 FIELD5 
1 1  2  3  4  5 
2 NULL 6  7  8  9 

DATA

ID PARENT_ID DATA1 DATA2 DATA3 
1 1   X  Y  J 
2 1   Z  W  U 
3 2   XY YX O 
4 2   ZW WZ I 

select d.* 
    from data d, conditional c 
where d.parent_id = c.id 
    and d.parent_id = 1 
order by 
     case 
      when c.field1 is null then 
       data1 asc, data2 desc 
      else 
       data3 asc, data1 desc 
     end 

在这个例子中,我选择了数据行ONE和TWO(父行id = 1的行)。 现在我已经做出了这个决定,我想根据CONDICTIONAL.FIELD1列的值来选择DATA列。我希望现在更加干净。

确定此查询确实有效,但这是“我需要的。”

+0

你可以给出示例数据和示例输出吗?事实上,目前还不清楚你想达到什么目的。 – GolezTrol 2014-09-25 07:19:53

+0

'ASC'和'DESC'是整个结果集的基础..不只是那一栏。 – 2014-09-25 07:26:50

+0

用示例编辑原始答案 – Mistre83 2014-09-25 07:27:54

回答

7

你可以有ORDER BY子句中CASE结构:

SQL> SELECT * FROM EMP T 
    2 ORDER BY 
    3 CASE 
    4  WHEN COMM IS NULL 
    5  THEN SAL 
    6  ELSE EMPNO 
    7 END 
    8/

    EMPNO ENAME  JOB    MGR HIREDATE   SAL  COMM  DEPTNO 
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 
     7369 SMITH  CLERK   7902 17-DEC-80  800     20 
     7900 JAMES  CLERK   7698 03-DEC-81  950     30 
     7876 ADAMS  CLERK   7788 23-MAY-87  1100     20 
     7934 MILLER  CLERK   7782 23-JAN-82  1300     10 
     7782 CLARK  MANAGER   7839 09-JUN-81  2450     10 
     7698 BLAKE  MANAGER   7839 01-MAY-81  2850     30 
     7566 JONES  MANAGER   7839 02-APR-81  2975     20 
     7788 SCOTT  ANALYST   7566 19-APR-87  3000     20 
     7902 FORD  ANALYST   7566 03-DEC-81  3000     20 
     7839 KING  PRESIDENT   17-NOV-81  5000     10 
     7499 ALLEN  SALESMAN  7698 20-FEB-81  1600  300   30 
     7521 WARD  SALESMAN  7698 22-FEB-81  1250  500   30 
     7654 MARTIN  SALESMAN  7698 28-SEP-81  1250  1400   30 
     7844 TURNER  SALESMAN  7698 08-SEP-81  1500   0   30 

14 rows selected. 

注意:照顾列的DATA TYPEORDER BY子句。

+0

感谢这是一个好的开始,但看看我原来的帖子更新。也许我忘了给你一些信息....我有两个表(或更多),其中一个是需要做出“选择”如何使订单。我在我的帖子上举了一个例子。 – Mistre83 2014-09-25 08:00:05

+0

检查Alex的回答,他已经进一步扩展以回答你的下一个问题。 – 2014-09-25 09:10:29

4

正如Lalit Kumar B所说,在order by条款中使用case。不能指定两个值或壳体内的递增/递减,所以你需要通过两个案例条款,重复相同的条件下命令:

select d.* 
    from data d, conditional c 
where d.parent_id = c.id 
    and d.parent_id = 1 
order by 
     case when c.field1 is null then d.data1 else d.data3 end asc, 
     case when c.field1 is null then d.data2 else d.data1 end desc; 

为您的样品数据得出:

 ID PARENT_ID DATA1 DATA2 DATA3 
---------- ---------- ----- ----- ----- 
     1   1 X  Y  J  
     2   1 Z  W  U  

或者适当连接语法,避免select *

select d.id, d.parent_id, d.data1, d.data2, d.data3 
    from data d 
    join conditional c 
    on c.id = d.parent_id 
where d.parent_id = 1 
order by 
     case when c.field1 is null then d.data1 else d.data3 end asc, 
     case when c.field1 is null then d.data2 else d.data1 end desc; 

Simple SQL Fiddle

+0

我正要编辑并在OP的新请求中添加更多答案,但您的答案已完成,因此我无需执行任何操作。谢谢;-) – 2014-09-25 09:02:38

+0

@LalitKumarB - 我不确定你是否打算扩展你的。如果你想修改你的答案,我可以删除这个 - 不要介意任何方式。 – 2014-09-25 09:09:46

+0

没有。不需要,你解释得相当不错。让它成为可能,因为它可以更好地理解OP的问题和澄清的流程。感谢您的回复:-) – 2014-09-25 09:11:46