关于SUM() OVER(ORDER BY ) 我有问题想请教
业务要求,取数时优先取有匹配序列号  (seqNo)的,然后按时间(dueDate)早晚,最后按金额(amount)大小。
sum(amount)  over(order by seqNo,dueDate,amount,id) 这样写的话,不符合要求,因为程序会按照seqNo的大小来排序,而业务并不需要按 seqNo的大小排序(seqNo 是 varchar2类型),表里面有些数据有 seqNo,有些没有  seqNo,所以只要把有seqNo的数据优先选取就行(没有seqNo 的数据也会选,只是它一定要排在 有seqNo数据的后面),然后再按时间和金额取。
我处理时制造了伪列 decode(seqNo,null,'10','1') as seqNo_seq  意图使有seqNo的数据为 '1', 没有 seqNo的数据为'10'这样程序就可以优先选取 有 seqNo的数据而又不会去比较那些seqNo的大小,但是最后运行的时候 sum(amount)  over(order by seqNo_seq,dueDate,amount,id) 却选不出任何数据了。
    还请各位前辈指点,谢谢。

解决方案 »

  1.   

    order by seqno nulls last
      

  2.   


    sum (amount) over(order by seqno nulls last,dueDate,amount,id)  这样写可以吗?
      

  3.   


    这样seqNo非空的记录还是有比较大小,我需要的效果是  seqNo 非空的记录是同等级别,然后按时间和金额排序   假设数据为  
    id   seqNo   dueDate   amount
     1     a1   2009-10-01   10
     2     a2   2009-09-01   20
     3          2009-09-01   30取数的id顺序应该是: 2,1,3  
      

  4.   

    order by nvl(seqno,'-1') ,dueDate,amount,id
    看看样可以吗
      

  5.   


    关键在于要让  seqno 是无序的
    这样处理  当seqNo非空时,还是有序的。  
      

  6.   

    select * from test  order by  decode(seqno,null,to_date('9999-12-31','YYYY-MM-DD'),dueDate),amount
      

  7.   

    按你的例子用
    order by seqno desc nulls last
    不就行了
      

  8.   

    sum(amount)over(order by seqNo,dueDate,amount nulls last rows between unbounded preceding and current row)
    不是说最后按amount排序吗,id是什么
    nulls last其实一般默认就是这样的,不加也罢
    出不来任何数据,没明白是怎么回事
    能给个测试的例子和数据吗
    可能没有完全理解你的意图
      

  9.   

    如楼上,要贴数据,不然情况太多:
    eg:
    假设数据为 : 
    假设数据为  
    id  seqNo  dueDate  amount 
    1    a1  2009-10-01  10 
    2    a2  2009-09-01  20 
    3          2009-09-01  30 
    2    a2  2009-09-01  20 
    假设数据为:  
    id  seqNo  dueDate  amount 
    1    a1  2009-10-01  10 
    2    a2  2009-09-01  20 
    3          2009-09-01  30 
    3          2009-09-02  30 etc以上的情况还有好多,要以那种为主? 都是为NULL的时候,又要以那个排序为主?
      

  10.   

    不知道楼主伪列是如何使用的,我的环境测试是成功的。
    SQL> select * from a;        C1         C2         C3
    ---------- ---------- ----------
             1          1          1
             2          2          4
             3          1          5
                        4          5SQL> select sum(c3) over(order by decode(c1,null,2,1),c2,c3) from a;SUM(C3)OVER(ORDERBYDECODE(C1,N
    ------------------------------
                                 1
                                 6
                                10
                                15
      

  11.   

    Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 
      

  12.   


    order by seqno desc nulls last这样做,seqNo 非空时是有序的,不符需求,当 seqNo 非空时,就要用 dueDate 排序, 而你这种会把seqNo非空的数据先按 seqNo排序,然后才按时间排,所以不行。
      

  13.   


    假设数据有15万条,sum(c3) over(order by decode(c1,null,2,1),c2,c3) 中的
    decode(c1,null,2,1) 会导致分析函数无法正常的求和,因为 decode(c1,null,2,1) 只有 2,1两种
      

  14.   

    明白了
    sum(amount)over(order by case when seqNo is not null then 1 end,dueDate,amount nulls last rows between unbounded preceding and current row) 
    试试
      

  15.   


    id 是主键,  amount 不是问题,不需要amount nulls last rows between unbounded preceding and current row 这么麻烦,  关键是对 seqNo 的排序问题,相当于只有 1和2的取值,非空的都是1,空的都是2 所以先取非空的,而非空的无需再去比较seqno的大小,直接拿dueDate排序
      

  16.   

    我的想法和10楼是一样的,decode后只有2种取值,代表空值和非空,为非空时,decode返回1,比较后面的参数来排序。为空时亦同
    不会按seqno排序
      

  17.   

    sum(amount)  over(order by seqNo_seq desc,dueDate,amount,id)