SELECT A,B,C  FROM TABLE_A 查詢出數據如下 
A  B    C 
aa bb  ak 
aa bb  af 
aa bb  mm 
ab de  45 
ab er  bb 
ab er  cc 
如何變成如下格式 
A  B    C 
aa  bb  ak 
        af 
        mm 
ab  de  45 
    er  bb 
        cc 就是名字是上一行一樣時顯示 NULl 

解决方案 »

  1.   

    SELECT CASE
             WHEN Q.A = LAG(A, 1, NULL) OVER(ORDER BY A) THEN
              NULL
             ELSE
              Q.A
           END A,
           CASE
             WHEN Q.B = LAG(B, 1, NULL) OVER(ORDER BY A) THEN
              NULL
             ELSE
              Q.B
           END B,
           CASE
             WHEN Q.C = LAG(C, 1, NULL) OVER(ORDER BY A) THEN
              NULL
             ELSE
              Q.C
           END C
    FROM (SELECT 'aa' A, 'bb' B, 'ak' C
              FROM DUAL
            UNION ALL
            SELECT 'aa' A, 'bb' B, 'af' C
              FROM DUAL
            UNION ALL
            SELECT 'aa' A, 'bb' B, 'mm' C
              FROM DUAL
            UNION ALL
            SELECT 'ab' A, 'de' B, '45' C
              FROM DUAL
            UNION ALL
            SELECT 'ab' A, 'er' B, 'bb' C
              FROM DUAL
            UNION ALL
            SELECT 'ab' A, 'er' B, 'cc' C FROM DUAL) Q
      

  2.   

    select decode(lag(a, 1) over(partition by a order by a), a, null, a) a,
           decode(lag(b, 1) over(partition by b order by b), b, null, b) b,
           c
      from table_a
     order by a, b
    剛剛測試了一下 上面語法可以實現
      

  3.   

    2樓的 把數據都寫死了 這只對上面這個有用﹔因為table 里的的數據是隨時可以改變的,不能寫死
      

  4.   

    LAG 功能描述:可以访问结果集中的其它行而不用进行自连接。它允许去处理游标,就好像游标是一个数组一样。在给定组中可参考当前行之前的行,这样就可以从组中与当前行一起选择以前的行。Offset是一个正整数,其默认值为1,若索引超出窗口的范围,就返回默认值(默认返回的是组中第一行),其相反的函数是LEAD
    SAMPLE:下面的例子中列prev_sal返回按hire_date排序的前1行的salary值
    SELECT last_name, hire_date, salary, LAG(salary, 1, 0) OVER (ORDER BY hire_date) AS prev_sal  FROM employees WHERE job_id = 'PU_CLERK';