ORACLE - 自定义ORDER BY来订购数据行对

时间:2016-04-01 10:27:00

标签: sql oracle

我有一张这样的桌子。

|DATE      |VOUCHER_NO|CURRENCY|AMOUNT|DESCRIPTION|JOURNAL_TYPE|COA_NO  |

|03/30/2016|0000000001|USD     |2000  |ABCD       |CREDIT      |150001  |
|03/30/2016|0000000001|USD     |2000  |ABCD       |DEBIT       |150001  |
|03/30/2016|0000000002|USD     |1500  |ABCD       |CREDIT      |150002  |
|03/30/2016|0000000002|USD     |1000  |ABCD       |DEBIT       |150002  |
|03/30/2016|0000000002|USD     |500   |ABCD       |DEBIT       |150002  |
|03/30/2016|0000000003|USD     |4000  |ABCD       |CREDIT      |150003  |
|03/30/2016|0000000003|USD     |2000  |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000003|USD     |1000  |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000003|USD     |500   |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000003|USD     |500   |ABCD       |DEBIT       |150003  |

我必须按最大金额对表格进行排序,首先是Journal Type Credit。然后必须依据基于Voucher_No的借方(不考虑借方的金额),然后紧接着第二大金额,就像这样。

|DATE      |VOUCHER_NO|CURRENCY|AMOUNT|DESCRIPTION|JOURNAL_TYPE|COA_NO  |

|03/30/2016|0000000003|USD     |4000  |ABCD       |CREDIT      |150003  |
|03/30/2016|0000000003|USD     |2000  |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000003|USD     |1000  |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000003|USD     |500   |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000003|USD     |500   |ABCD       |DEBIT       |150003  |
|03/30/2016|0000000001|USD     |2000  |ABCD       |CREDIT      |150001  |  
|03/30/2016|0000000001|USD     |2000  |ABCD       |DEBIT       |150001  | 
|03/30/2016|0000000002|USD     |1500  |ABCD       |CREDIT      |150002  |
|03/30/2016|0000000002|USD     |1000  |ABCD       |DEBIT       |150002  |
|03/30/2016|0000000002|USD     |500   |ABCD       |DEBIT       |150002  |

怎么做?如果我先按金额订购,借记卡将分散到下方,如果我先按voucher_no订购,则不会按金额订购。

3 个答案:

答案 0 :(得分:4)

您可以先ORDER BY 群组总和,就像这样

ORDER BY
   MAX(AMOUNT) OVER (PARTITION BY VOUCHER_NO) DESC, -- voucher with highest amount first
   VOUCHER_NO,  -- all rows of that voucher
   CASE WHEN JOURNAL_TYPE = 'CREDIT' THEN 0 ELSE 1 END, -- credit first
   AMOUNT DESC

答案 1 :(得分:2)

这应该可以解决问题:

with your_table as (select to_date('30/03/2016', 'dd/mm/yyyy') dt, 1 voucher_no, 'USD' currency, 2000 amount, 'ABCD' description, 'Credit' journal_type, 150001 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 1 voucher_no, 'USD' currency, 2000 amount, 'ABCD' description, 'Debit' journal_type, 150001 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 2 voucher_no, 'USD' currency, 1500 amount, 'ABCD' description, 'Credit' journal_type, 150002 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 2 voucher_no, 'USD' currency, 1000 amount, 'ABCD' description, 'Debit' journal_type, 150002 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 2 voucher_no, 'USD' currency, 500 amount, 'ABCD' description, 'Debit' journal_type, 150002 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 3 voucher_no, 'USD' currency, 4000 amount, 'ABCD' description, 'Credit' journal_type, 150003 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 3 voucher_no, 'USD' currency, 2000 amount, 'ABCD' description, 'Debit' journal_type, 150003 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 3 voucher_no, 'USD' currency, 1000 amount, 'ABCD' description, 'Debit' journal_type, 150003 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 3 voucher_no, 'USD' currency, 500 amount, 'ABCD' description, 'Debit' journal_type, 150003 coa_no from dual union all
                    select to_date('30/03/2016', 'dd/mm/yyyy') dt, 3 voucher_no, 'USD' currency, 500 amount, 'ABCD' description, 'Debit' journal_type, 150003 coa_no from dual)
-- End of mimicking your table with data in. See SQL below:
select *
from   your_table
order by max(amount) over (partition by voucher_no) desc,
         journal_type,
         amount desc;

DT         VOUCHER_NO CURRENCY     AMOUNT DESCRIPTION JOURNAL_TYPE     COA_NO
---------- ---------- -------- ---------- ----------- ------------ ----------
30/03/2016          3 USD            4000 ABCD        Credit           150003
30/03/2016          3 USD            2000 ABCD        Debit            150003
30/03/2016          3 USD            1000 ABCD        Debit            150003
30/03/2016          3 USD             500 ABCD        Debit            150003
30/03/2016          3 USD             500 ABCD        Debit            150003
30/03/2016          1 USD            2000 ABCD        Credit           150001
30/03/2016          1 USD            2000 ABCD        Debit            150001
30/03/2016          2 USD            1500 ABCD        Credit           150002
30/03/2016          2 USD            1000 ABCD        Debit            150002
30/03/2016          2 USD             500 ABCD        Debit            150002

注意,如果您要在子查询中使用此查询,显然您必须将max(amount) over (partition by voucher_no)添加到选择列列表中,以便将该列公开给外部查询。

ETA。如果您的借方金额大于贷方金额,并且您在首先显示信用额度最高的凭证代码行之后,则更改:

max(amount) over (partition by voucher_no)

max(case when journal_type = 'Credit' then amount end) over (partition by voucher_no)

答案 2 :(得分:0)

我不确定,但一次检查

     SELECT * from ... ORDER BY JOURNAL_TYPE asc, AMOUNT asc;

编辑1: - 明白你的问题,让我重新编辑我的答案 编辑2: - 用户dnoeth
已经发布了正确的答案 注意: - 这不是正确的答案