Oracle中分組查詢時keep的使用[轉][

47328983發表於2013-02-07

for   example:  
   
  15:18:59   SQL>   create   table   t1   (a   int,   b   int);  
   
  表已建立。  
   
  已用時間:     00:   00:   00.15  
  15:18:59   SQL>  
  15:18:59   SQL>   insert   into   t1   values   (1,5);  
   
  已建立   1   行。  
   
  已用時間:     00:   00:   00.16  
  15:18:59   SQL>   insert   into   t1   values   (1,3);  
   
  已建立   1   行。  
   
  已用時間:     00:   00:   00.16  
  15:18:59   SQL>   insert   into   t1   values   (1,4);  
   
  已建立   1   行。  
   
  已用時間:     00:   00:   00.15  
  15:18:59   SQL>   insert   into   t1   values   (2,1);  
   
  已建立   1   行。  
   
  已用時間:     00:   00:   00.16  
  15:18:59   SQL>   insert   into   t1   values   (2,3);  
   
  已建立   1   行。  
   
  已用時間:     00:   00:   00.00  
  15:18:59   SQL>  
  15:18:59   SQL>   SELECT  
  15:18:59       2     max(b)   KEEP   (DENSE_RANK   LAST   ORDER   BY   (a)   desc)   AS   last,  
  15:18:59       3     max(b)   KEEP   (DENSE_RANK   FIRST   ORDER   BY   (a)   desc)   AS   first  
  15:18:59       4     FROM   t1;  
   
              LAST             FIRST  
  ----------   ----------  
                    5                     3  
   
  已用時間:     00:   00:   00.00

SQL含義:  

  從DENSE_RANK取出的結果集中取出最小的一項(以a排序),可能取出多行,因為a值可能相同。再從這些行中取出b欄位最大的一行。
  選出  
  以欄位a分組,最小一組中(LAST   降序)所有記錄中b的最大值  
  和  
  以欄位a分組,最大一組中(FRIST   降序)所有記錄中b的最大值

Returns the row ranked first using DENSE_RANK
2種取值:
DENSE_RANK FIRST
DENSE_RANK LAST

keep (DENSE_RANK first
ORDER BY sl) 結果集中再取max、min的例子。


SQL
> select * from test;

ID MC SL
-------------------- -------------------- -------------------
1 111 1
1 222 1
1 333 2
1 555 3
1 666 3
2 111 1
2 222 1
2 333 2
2 555 2

9 rows selected

SQL
>
SQL
> select id,mc,sl,
2 min(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id),
3 max(mc) keep (DENSE_RANK last ORDER BY sl) over(partition by id)
4 from test
5 ;

ID MC SL
MIN(MC)KEEP(DENSE_RANKFIRSTORD MAX(MC)KEEP(DENSE_RANKLASTORDE
-------------------- -------------------- ------------------- ------------------------------ ------------------------------
1 111 1 111 666
1 222 1 111 666
1 333 2 111 666
1 555 3 111 666
1 666 3 111 666
2 111 1 111 555
2 222 1 111 555
2 333 2 111 555
2 555 2 111 555

9 rows selected

SQL
>

不要混淆keep內(firstlast)外(
min、max或者其他):
min是可以對應last
max是可以對應first

SQL
> select id,mc,sl,
2 min(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id),
3 max(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id),
4 min(mc) keep (DENSE_RANK last ORDER BY sl) over(partition by id),
5 max(mc) keep (DENSE_RANK last ORDER BY sl) over(partition by id)
6 from test
7 ;

ID MC SL
MIN(MC)KEEP(DENSE_RANKFIRSTORD MAX(MC)KEEP(DENSE_RANKFIRSTORD MIN(MC)KEEP(DENSE_RANKLASTORDE MAX(MC)KEEP(DENSE_RANKLASTORDE
-------------------- -------------------- ------------------- ------------------------------ ------------------------------ ------------------------------ ------------------------------
1 111 1 111 222 555 666
1 222 1 111 222 555 666
1 333 2 111 222 555 666
1 555 3 111 222 555 666
1 666 3 111 222 555 666
2 111 1 111 222 333 555
2 222 1 111 222 333 555
2 333 2 111 222 333 555
2 555 2 111 222 333 555

9 rows selected


SQL
> select id,mc,sl,
2 min(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id),
3 max(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id),
4 min(mc) keep (DENSE_RANK last ORDER BY sl) over(partition by id),
5 max(mc) keep (DENSE_RANK last ORDER BY sl) over(partition by id)
6 from test
7 ;

ID MC SL
MIN(MC)KEEP(DENSE_RANKFIRSTORD MAX(MC)KEEP(DENSE_RANKFIRSTORD MIN(MC)KEEP(DENSE_RANKLASTORDE MAX(MC)KEEP(DENSE_RANKLASTORDE
-------------------- -------------------- ------------------- ------------------------------ ------------------------------ ------------------------------ ------------------------------
1 111 1 111 222 555 666
1 222 1 111 222 555 666
1 333 2 111 222 555 666
1 555 3 111 222 555 666
1 666 3 111 222 555 666

2 111 1 111 222 333 555
2 222 1 111 222 333 555
2 333 2 111 222 333 555
2 555 2 111 222 333 555

min(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id):id等於1的數量最小的(DENSE_RANK first )為
1 111 1
1 222 1
在這個結果中取min(mc) 就是111
max(mc) keep (DENSE_RANK first ORDER BY sl) over(partition by id)
取max(mc) 就是222;
min(mc) keep (DENSE_RANK last ORDER BY sl) over(partition by id):id等於1的數量最大的(DENSE_RANK first )為
1 555 3
1 666 3
在這個結果中取min(mc) 就是222,取max(mc)就是666

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/241379/viewspace-753989/,如需轉載,請註明出處,否則將追究法律責任。

相關文章