Oracle keep的用法
keep是Oracle下的另一個分析函式,他的用法不同於透過over關鍵字指定的分析函式,可以用於這樣一種場合下:取同一個分組下以某個欄位排序後,對指定欄位取最小或最大的那個值。
從這個前提出發,我們可以看到其實這個目標透過一般的row_number分析函式也可以實現,即指定rn=1。但是,該函式無法實現同時獲取最大和最小值。或者說用first_value和last_value,結合row_number實現,但是該種方式需要多次使用分析函式,而且還需要套一層SQL。於是出現了keep,該函式先可以參考如下連結:
具體例子,假設有如下資料:
SQL> with
2 tmp as (
3 select 'a,20110201,111' a from dual union all
4 select 'a,20110202,222' from dual union all
5 select 'a,20110302,333' from dual union all
6 select 'a,20110403,555' from dual union all
7 select 'a,20110403,666' from dual union all
8 select 'b,20110201,111' from dual union all
9 select 'b,20110202,222' from dual union all
10 select 'b,20110302,333' from dual union all
11 select 'b,20110402,555' from dual),
12 tt as (select pkg_dc_public.strpart(a,1) netno,
13 to_date(pkg_dc_public.strpart(a,2), 'yyyymmdd') sale_date,
14 pkg_dc_public.strpart(a,3) sale_count
15 from tmp)
16 select * from tt
17 /
NETNO SALE_DATE SALE_COUNT
-------- ----------- --------------
a 2011-2-1 111
a 2011-2-2 222
a 2011-3-2 333
a 2011-4-3 555
a 2011-4-3 666
b 2011-2-1 111
b 2011-2-2 222
b 2011-3-2 333
b 2011-4-2 555
9 rows selected
假設資料是各網點幾天的銷售資料
欄位netno是網點標識,這裡有a網點和b網點;
欄位sale_count是銷售量;
欄位sale_date是銷售量統計日期。
現要取a網點中:
最早那個月最小的銷量
最早那個月最大的銷量
最近一個月最小的銷量
最近一個月最大的銷量
SQL> with
2 tmp as (
3 select 'a,20110201,111' a from dual union all
4 select 'a,20110202,222' from dual union all
5 select 'a,20110302,333' from dual union all
6 select 'a,20110403,555' from dual union all
7 select 'a,20110403,666' from dual union all
8 select 'b,20110201,111' from dual union all
9 select 'b,20110202,222' from dual union all
10 select 'b,20110302,333' from dual union all
11 select 'b,20110402,555' from dual),
12 tt as (select pkg_dc_public.strpart(a,1) netno,
13 to_date(pkg_dc_public.strpart(a,2), 'yyyymmdd') sale_date,
14 pkg_dc_public.strpart(a,3) sale_count
15 from tmp)
16 --select * from tt
17 select netno,
18 min(sale_count)keep(dense_rank first order by trunc(sale_date,'mm')) fst_min,
19 min(sale_count)keep(dense_rank last order by trunc(sale_date,'mm')) lst_min,
20 max(sale_count)keep(dense_rank first order by trunc(sale_date,'mm')) fst_max,
21 max(sale_count)keep(dense_rank last order by trunc(sale_date,'mm')) lst_max
22 from tt t
23 group by netno
24 /
NETNO FST_MIN LST_MIN FST_MAX LST_MAX
----------- ------------ ------------ ------------ -----------
a 111 555 222 666
b 111 555 222 555
從這個前提出發,我們可以看到其實這個目標透過一般的row_number分析函式也可以實現,即指定rn=1。但是,該函式無法實現同時獲取最大和最小值。或者說用first_value和last_value,結合row_number實現,但是該種方式需要多次使用分析函式,而且還需要套一層SQL。於是出現了keep,該函式先可以參考如下連結:
具體例子,假設有如下資料:
SQL> with
2 tmp as (
3 select 'a,20110201,111' a from dual union all
4 select 'a,20110202,222' from dual union all
5 select 'a,20110302,333' from dual union all
6 select 'a,20110403,555' from dual union all
7 select 'a,20110403,666' from dual union all
8 select 'b,20110201,111' from dual union all
9 select 'b,20110202,222' from dual union all
10 select 'b,20110302,333' from dual union all
11 select 'b,20110402,555' from dual),
12 tt as (select pkg_dc_public.strpart(a,1) netno,
13 to_date(pkg_dc_public.strpart(a,2), 'yyyymmdd') sale_date,
14 pkg_dc_public.strpart(a,3) sale_count
15 from tmp)
16 select * from tt
17 /
NETNO SALE_DATE SALE_COUNT
-------- ----------- --------------
a 2011-2-1 111
a 2011-2-2 222
a 2011-3-2 333
a 2011-4-3 555
a 2011-4-3 666
b 2011-2-1 111
b 2011-2-2 222
b 2011-3-2 333
b 2011-4-2 555
9 rows selected
假設資料是各網點幾天的銷售資料
欄位netno是網點標識,這裡有a網點和b網點;
欄位sale_count是銷售量;
欄位sale_date是銷售量統計日期。
現要取a網點中:
最早那個月最小的銷量
最早那個月最大的銷量
最近一個月最小的銷量
最近一個月最大的銷量
SQL> with
2 tmp as (
3 select 'a,20110201,111' a from dual union all
4 select 'a,20110202,222' from dual union all
5 select 'a,20110302,333' from dual union all
6 select 'a,20110403,555' from dual union all
7 select 'a,20110403,666' from dual union all
8 select 'b,20110201,111' from dual union all
9 select 'b,20110202,222' from dual union all
10 select 'b,20110302,333' from dual union all
11 select 'b,20110402,555' from dual),
12 tt as (select pkg_dc_public.strpart(a,1) netno,
13 to_date(pkg_dc_public.strpart(a,2), 'yyyymmdd') sale_date,
14 pkg_dc_public.strpart(a,3) sale_count
15 from tmp)
16 --select * from tt
17 select netno,
18 min(sale_count)keep(dense_rank first order by trunc(sale_date,'mm')) fst_min,
19 min(sale_count)keep(dense_rank last order by trunc(sale_date,'mm')) lst_min,
20 max(sale_count)keep(dense_rank first order by trunc(sale_date,'mm')) fst_max,
21 max(sale_count)keep(dense_rank last order by trunc(sale_date,'mm')) lst_max
22 from tt t
23 group by netno
24 /
NETNO FST_MIN LST_MIN FST_MAX LST_MAX
----------- ------------ ------------ ------------ -----------
a 111 555 222 666
b 111 555 222 555
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12932950/viewspace-687036/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle KEEP池的CACHE特點Oracle
- Oracle 的 KEEP pool, RECYCLE pool和DEFAULT poolOracle
- Oracle中分組查詢時keep的使用[轉][Oracle
- oracle分析函式,keep and over解說Oracle函式
- Oracle Hints的用法Oracle
- oracle job的用法Oracle
- Oracle Analyze的用法Oracle
- Oracle中with的用法Oracle
- Oracle Hint的用法Oracle
- Oracle的Cast的用法OracleAST
- ORACLE WITH AS 用法Oracle
- oracle comment on的用法Oracle
- oracle explain plan for的用法OracleAI
- 【 Oracle中rownum的用法 】Oracle
- Oracle set unused的用法Oracle
- oracle的interval用法特例Oracle
- Oracle 的 bulk collect用法Oracle
- (轉)Oracle Hint的用法Oracle
- Oracle 中 case的用法Oracle
- oracle樹中prior的用法Oracle
- 【Oracle的NVL函式用法】Oracle函式
- Oracle中rowid的用法Oracle
- 【oracle中rowid的用法】Oracle
- Oracle dump函式的用法Oracle函式
- Oracle trunc()函式的用法Oracle函式
- Oracle Hints語句的用法Oracle
- Oracle 函式 Translate 的用法Oracle函式
- oracle的with函式用法示例Oracle函式
- 常見Oracle HINT的用法Oracle
- ORACLE SQL的EXCEPT、INTERSECT用法OracleSQL
- oracle中copy from的用法Oracle
- 談談Oracle interMedia的用法Oracle
- Oracle set unused的用法.sqlOracleSQL
- oracle臨時表的用法Oracle
- ORACLE SEQUENCE用法Oracle
- oracle cast 用法OracleAST
- oracle job用法Oracle
- oracle restrice用法OracleREST