1.排名函数:
RANK and DENSE_RANK Functions
语法如下:
RANK ( ) OVER ( [query_partition_clause] order_by_clause )
DENSE_RANK ( ) OVER ( [query_partition_clause]order_by_clause )
在排名函数中order by是不可选字段,表示你要按什么进行排名,partition是可选字段,如果没有partition则表示对全部数据进行排名,如果有partition则表示在分区内进行排序。
我们先来看一个例子:
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(SAL) SAL,
4 RANK() OVER(ORDER BY SUM(SAL) DESC)RANK_DESC,
5 RANK() OVER(ORDER BY SUM(SAL))RANK_ASC,
6 DENSE_RANK() OVER(ORDER BY SUM(SAL)DESC) DENSE
7 FROM EMP
8 GROUP BY DEPTNO, EMPNO;
EMPNO DEPTNO SAL RANK_DESC RANK_ASC DENSE
---------- ---------- ---------- ---------- --------------------
7900 30 950 14 1 12
7876 20 1100 13 2 11
7521 30 1250 11 3 10
7654 30 1250 11 3 10
7934 10 1300 10 5 9
7844 30 1500 9 6 8
7499 30 1600 8 7 7
7782 10 2450 7 8 6
7698 30 2850 6 9 5
7566 20 2975 5 10 4
7902 20 3000 3 11 3
EMPNO DEPTNO SAL RANK_DESC RANK_ASC DENSE
---------- ---------- ---------- ---------- --------------------
7788 20 3000 3 11 3
7839 10 5000 2 13 2
7369 20 10000 1 14 1
已选择14行。
在以上这个例子中我们可以看到,oracle默认是按照asc进行排名的,rank函数的排名是有间隙的,比如说上面两个11名,接下来就是13名,而dense_rank是没有间隙的。
接下来看一下partition是如何处理的
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(SAL) SAL,
4 RANK() OVER(PARTITION BY deptno ORDERBY SUM(SAL) DESC) rank_par
5 FROM EMP
6 GROUP BY DEPTNO, EMPNO;
EMPNO DEPTNO SAL RANK_PAR
---------- ---------- ---------- ----------
7839 10 5000 1
7782 10 2450 2
7934 10 1300 3
7369 20 10000 1
7788 20 3000 2
7902 20 3000 2
7566 20 2975 4
7876 20 1100 5
7698 30 2850 1
7499 30 1600 2
7844 30 1500 3
EMPNO DEPTNO SAL RANK_PAR
---------- ---------- ---------- ----------
7521 30 1250 4
7654 30 1250 4
7900 30 950 6
已选择14行。
可以看到oracle在deptno内进行了排序,也就是以deptno为分区进行排序。
NTILEFunction
语法如下:
NTILE (expr) OVER([query_partition_clause] order_by_clause)
ntile函数会按照order by对数据进行切片,但是有一个比较有趣的情况,那就是当数据不能平分时,Oracle会将不能平分的数据按照片号从高到低一个一个的分配,例子如下:
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(SAL) SAL,
4 ntile(4) OVER(ORDER BY SUM(SAL) DESC)til
5 FROM EMP
6 GROUP BY DEPTNO,EMPNO;
EMPNO DEPTNO SAL TILE
---------- ---------- ---------- ----------
7369 20 10000 1
7839 10 5000 1
7788 20 3000 1
7902 20 3000 1
7566 20 2975 2
7698 30 2850 2
7782 10 2450 2
7499 30 1600 2
7844 30 1500 3
7934 10 1300 3
7654 30 1250 3
EMPNO DEPTNO SAL TILE
---------- ---------- ---------- ----------
7521 30 1250 4
7876 20 1100 4
7900 30 950 4
ROW_NUMBERFunction
ROW_NUMBER ( ) OVER ([query_partition_clause] order_by_clause )
这个函数会根据order by对每一行分配一个特定的编号,从1开始。例子如下:
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(SAL) SAL,
4 row_number() OVER(ORDER BY SUM(SAL)DESC) row_number
5 FROM EMP
6 GROUP BY DEPTNO,EMPNO;
EMPNO DEPTNO SAL ROW_NUMBER
---------- ---------- ---------- ----------
7369 20 10000 1
7839 10 5000 2
7788 20 3000 3
7902 20 3000 4
7566 20 2975 5
7698 30 2850 6
7782 10 2450 7
7499 30 1600 8
7844 30 1500 9
7934 10 1300 10
7654 30 1250 11
EMPNO DEPTNO SAL ROW_NUMBER
---------- ---------- ---------- ----------
7521 30 1250 12
7876 20 1100 13
7900 30 950 14
其它一些函数并不常用,请参照官方文档。
2.window函数
先来看看Oracle官方文档的介绍吧
Windowing functions can be used to computecumulative, moving, and centered aggregates. They return a value for each rowin the table, which depends on other rows in the corresponding window. Withwindowing aggregate functions, you can calculate moving andcumulative versions of SUM, AVERAGE, COUNT, MAX,MIN, andmany more functions. They can be used only inthe SELECT and ORDER BY clauses of the query.Windowing aggregate functions include the convenientFIRST_VALUE, which returnsthe first value in the window; and LAST_VALUE, which returns the lastvalue in the window. These functions provide access to more than one row of atable without a self-join.
语法如下:
analytic_function([arguments ])
OVER (analytic_clause)
where analytic_clause=
[ query_partition_clause ]
[ order_by_clause [ windowing_clause] ]
andquery_partition_clause =
PARTITION BY
{ value_expr[, value_expr ]...
}
and windowing_clause =
{ ROWS | RANGE }
{ BETWEEN
{ UNBOUNDED PRECEDING
| CURRENT ROW
| value_expr { PRECEDING | FOLLOWING}
}
AND
{ UNBOUNDED FOLLOWING
| CURRENT ROW
| value_expr { PRECEDING | FOLLOWING}
}
| { UNBOUNDED PRECEDING
| CURRENT ROW
| value_expr PRECEDING
}
}
在了解之前先了解一下rows和range的区别,
rows表示一个物理窗口,也就是排序后,按排序结果的行号对应确定窗口
Range是默认窗口,表示一个行和行之间的逻辑关系(当前行的排序键的value加或减逻辑偏移量得到当前行对应的逻辑窗口的范围)
Cumulative Aggregate Function
下面这个例子表示对一个部门的工资进行累加
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(sal),
4 SUM(SAL) OVER(
5 PARTITION BY deptno ORDER BY empno DESCROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
6 ) row_number
7 FROM EMP
8 GROUP BY DEPTNO,EMPNO,sal;
EMPNO DEPTNO SUM(SAL) ROW_NUMBER
---------- -------------------- ----------
7934 10 1300 1300
7839 10 5000 6300
7782 10 2450 8750
7902 20 3000 3000
7876 20 1100 4100
7788 20 3000 7100
7566 20 2975 10075
7369 20 10000 20075
7900 30 950 950
7844 30 1500 2450
7698 30 2850 5300
EMPNO DEPTNO SUM(SAL) ROW_NUMBER
---------- -------------------- ----------
7654 30 1250 6550
7521 30 1250 7800
7499 30 1600 9400
这个例子中,窗口开始于partition by的第一条数据,结束于当前行,oracle默认的结束为currentrow
MovingAggregate Function
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(sal),
4 SUM(SAL) OVER(
5 PARTITION BY deptno ORDER BY empno DESC ROWS BETWEEN 1 PRECEDING AND 1Following
6 ) rows_sum
7 FROMEMP
8 GROUP BY DEPTNO,EMPNO,sal;
EMPNO DEPTNO SUM(SAL) ROWS_SUM
---------- -------------------- ----------
7934 10 1300 6300 --这个表示1 PRECEDING,就是向前推进一行
7839 10 5000 8750 --假如这个是当前行
7782 10 2450 7450 --这个表示1 Following,就是向后推进一行
7902 20 3000 4100
7876 20 1100 7100
7788 20 3000 7075
7566 20 2975 15975
7369 20 10000 12975
7900 30 950 2450
7844 30 1500 5300
7698 30 2850 5600
EMPNO DEPTNO SUM(SAL) ROWS_SUM
---------- ---------- --------------------
7654 30 1250 5350
7521 30 1250 4100
7499 30 1600 2850
下面我们来看range是怎么样进行偏移的。
CenteredAggregate Function
SQL> SELECT EMPNO,
2 DEPTNO,
3 SUM(SAL),
4 SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL DESC RANGE BETWEEN 10
0 PRECEDING AND 300FOLLOWING) ROWS_SUM
5 FROM EMP
6 GROUP BY DEPTNO, EMPNO, SAL;
EMPNO DEPTNO SUM(SAL) ROWS_SUM
---------- ---------- --------------------
7839 10 5000 5000
7782 10 2450 2450
7934 10 1300 1300
7369 20 10000 10000
7788 20 3000 8975
7902 20 3000 8975
7566 20 2975 8975
7876 20 1100 1100
7698 30 2850 2850
7499 30 1600 3100 ----开始处
7844 30 1500 5600 --假如这个是当前行,那么上面就表示的范围是1500-300=1200 1600之间
EMPNO DEPTNO SUM(SAL) ROWS_SUM
---------- -------------------- ----------
7521 30 1250 3450
7654 30 1250 3450--结束处
7900 30 950 950
升序range窗口preceding含义是比当前行小xx值,following含义是比当前行大xx值,降序range窗口preceding含义是比当前行大xx值,following含义是比当前行小xx值。
3.Reporting函数
语法如下:
{SUM |AVG | MAX | MIN | COUNT | STDDEV | VARIANCE ... }
([ALL | DISTINCT] {value expression1[,...] | *})
OVER ([PARTITION BY valueexpression2[,...]])
这个比较简单不在用实例说明了。
RATIO_TO_REPORTFunction
语法如下:RATIO_TO_REPORT( expr ) OVER ( [query_partition_clause] )
这个函数表示expr这个值在expr所在字段和中所占的比例,实例如下:
SQL> SELECT DEPTNO,
2 EMPNO,
3 SUM(SAL) SAL,
4 SUM(SAL) OVER() TOTAL,
5 to_char(RATIO_TO_REPORT(SUM(sal))OVER(),'9990.99') RATIO
6 FROM EMP
7 GROUP BY DEPTNO, EMPNO,sal;
DEPTNO EMPNO SAL TOTAL RATIO
---------- ---------- ---------- ---------- --------
30 7499 1600 38225 0.04 --1600/38225
20 7566 2975 38225 0.08
20 7788 3000 38225 0.08
10 7839 5000 38225 0.13
20 7876 1100 38225 0.03
20 7369 10000 38225 0.26
30 7654 1250 38225 0.03
30 7521 1250 38225 0.03
20 7902 3000 38225 0.08
10 7782 2450 38225 0.06
10 7934 1300 38225 0.03
DEPTNO EMPNO SAL TOTAL RATIO
---------- ---------- ---------- ---------- --------
30 7698 2850 38225 0.07
30 7844 1500 38225 0.04
30 7900 950 38225 0.02
4.LAG/LEAD
语法如下:
{LAG | LEAD} (value_expr [, offset] [, default] ) [RESPECT NULLS|IGNORE NULLS]
OVER ( [query_partition_clause] order_by_clause)
Offset 表示偏移量,当指定ignore nulls在发生偏移时oracle会忽略null。
例子如下:
SQL> SELECT DEPTNO,
2 empno,
3 sal,
4 LAG(sal,1) OVER(ORDER BY EMPNO DESC)LA,
5 LEAD(SAL,1) OVER(ORDER BY EMPNO DESC)LE
6 FROM EMP
7 GROUP BY DEPTNO,empno,sal;
DEPTNO EMPNO SAL LA LE
---------- ---------- ---------- ---------- ----------
10 7934 1300 3000
20 7902 3000 1300 950
30 7900 950 3000 1100
20 7876 1100 950 1500
30 7844 1500 1100 5000
10 7839 5000 1500 3000
20 7788 3000 5000 2450
10 7782 2450 3000 2850
30 7698 2850 2450 1250
30 7654 1250 2850 2975
20 7566 2975 1250 1250
DEPTNO EMPNO SAL LA LE
---------- ---------- ---------- ---------- ----------
30 7521 1250 2975 1600
30 7499 1600 1250 10000
20 7369 10000 1600
5.FIRST_VALUEand LAST_VALUE Functions
语法如下:
FIRST_VALUE|LAST_VALUE( <expr> ) [RESPECT NULLS|IGNORE NULLS] OVER (analytic clause );
这个函数用来返回窗口的第一个值或者最后一个值,但是这个有一个有趣的例子,我们来看看
先来看一个例子:
SQL> SELECT DEPTNO,
2 EMPNO,
3 sal,
4 FIRST_VALUE(SAL) OVER(PARTITION BYDEPTNO ORDER BY EMPNO ROWS betwee
n unbounded preceding and current row) FIRST,
5 LAST_VALUE(SAL) OVER(PARTITION BYDEPTNO ORDER BY empno rows between
unbounded precedingand unbounded following) LAST,
6 LAST_VALUE(SAL) OVER(PARTITION BYDEPTNO ORDER BY empno rows between
unbounded precedingand current row) LAST2,
7 LAST_VALUE(SAL) OVER(PARTITION BYDEPTNO ORDER BY empno) last3
8 FROM EMP
9 ;
DEPTNO EMPNO SAL FIRST LAST LAST2 LAST3
---------- ---------- ---------- ---------- -------------------- ----------
10 7782 2450 2450 1300 2450 2450
10 7839 5000 2450 1300 5000 5000
10 7934 1300 2450 1300 1300 1300
20 7369 10000 10000 3000 10000 10000
20 7566 2975 10000 3000 2975 2975
20 7788 3000 10000 3000 3000 3000
20 7876 1100 10000 3000 1100 1100
20 7902 3000 10000 3000 3000 3000
30 7499 1600 1600 950 1600 1600
30 7521 1250 1600 950 1250 1250
30 7654 1250 1600 950 1250 1250
DEPTNO EMPNO SAL FIRST LAST LAST2 LAST3
---------- ---------- ---------- ---------- -------------------- ----------
30 7698 2850 1600 950 2850 2850
30 7844 1500 1600 950 1500 1500
30 7900 950 1600 950 950 950
看last3字段不是应该返回窗口的最后一个值吗,但是结果总是让人失望的,下面是我在pub上找到的一位大神的解释。
--大神的解释
对于分析函数,大家要注意:
1. 分析函数是在整个SQL查询结束后(SQL语句中的ORDERBY的执行比较特殊)再进行的操作,也就是说
SQL语句中的ORDER BY也会影响分析函数的执行结果,请看:
SQL> select deptno,
2 empno,
3 ename,
4 sal,
5 hiredate,
6 last_value(sal) over(partition by deptno) last_value
7 from emp
8 where deptno =30;
DEPTNO EMPNO ENAME SAL HIREDATE last_value
------ ----- ---------- -------------------- -----------
30 7499ALLEN 1600.00 1981-02-20 950
30 7521WARD 1250.00 1981-02-22 950
30 7654MARTIN 1250.00 1981-09-28 950
30 7698BLAKE 2850.00 1981-05-01 950
30 7844TURNER 1500.00 1981-09-08 950
30 7900JAMES 950.00 1981-12-03 950
6 rows selected
SQL> select deptno,
2 empno,
3 ename,
4 sal,
5 hiredate,
6 last_value(sal) over(partition by deptno) last_value
7 from emp
8 where deptno =30
9 order bydeptno,mgr;
DEPTNO EMPNO ENAME SAL HIREDATE last_value
------ ----- ---------- -------------------- -----------
30 7499ALLEN 1600.00 1981-02-20 2850
30 7521WARD 1250.00 1981-02-22 2850
30 7654MARTIN 1250.00 1981-09-28 2850
30 7900JAMES 950.00 1981-12-03 2850
30 7844 TURNER 1500.00 1981-09-08 2850
30 7698BLAKE 2850.00 1981-05-01 2850
6 rows selected
SQL> select deptno,
2 empno,
3 ename,
4 sal,
5 hiredate,
6 last_value(sal) over(partition by deptno) last_value
7 from emp
8 where deptno =30
9 order bydeptno,mgr desc;
DEPTNO EMPNO ENAME SAL HIREDATE last_value
------ ----- ---------- -------------------- -----------
30 7698 BLAKE 2850.00 1981-05-01 1250
30 7499ALLEN 1600.00 1981-02-20 1250
30 7521WARD 1250.00 1981-02-22 1250
30 7900JAMES 950.00 1981-12-03 1250
30 7844TURNER 1500.00 1981-09-08 1250
30 7654MARTIN 1250.00 1981-09-28 1250
6 rows selected
从上面的结果我们分析得出:
a) 如果SQL语句中的OrderBy满足分析函数分析时要求的排序,那么SQL语句中的排序将先执行,分析
函数分析时就不必再排序
b) 如果SQL语句中的OrderBy不满足分析函数分析时要求的排序,那么SQL语句中的排序将最后在分
析函数分析结束后执行排序
2. 分析函数中包含三个分析子句:分组(Partition By), 排序(OrderBy),窗口(Window)
窗口就是分析函数分析时要处理的数据范围,就拿SUM来说,它是SUM窗口中的记录而不是整个分组中
的记录,因此我们在想得到某个栏位的累计值时,我们需要把窗口指定到该分组中的第一行数据到当
前行,如果你指定该窗口从该分组中的第一行到最后一行,那么该组中的每一个SUM值都会一样,即整
个组的总和.
窗口子句在这里我只说rows方式的窗口,range方式的这里不提,此外滑动窗口也不提.窗口子句中
我们经常用到指定第一行,当前行,最后一行这样的三个属性.第一行是unbounded preceding,当
前行是 current row,最后一行是unbounded following.
出现窗口子句,必须指定Order By子句,如:
last_value(sal) over
(partition by deptno order by sal rowsbetween unbounded preceding and unbounded following)
以上示例指定窗口为整个分组.
当省略窗口子句时:
a) 如果存在Order By则默认的窗口是unboundedpreceding and current row
b) 如果同时省略Order By则默认的窗口是unboundedpreceding and unbounded following
如果省略分组,则把全部记录当成一个组:
a) 如果存在Order By则默认窗口是unboundedpreceding and current row
b) 如果这时省略Order By则窗口默认为unboundedpreceding and unbounded following
来自 <http://www.itpub.net/thread-717608-2-1.html>
Advanced Aggregates for Analysis
LISTAGG Function
这个函数是11g新提出来的,语法如下:
LISTAGG (<expr>[, <delimiter>) WITHIN GROUP (ORDER BY <oby_expression_list>)
Expr表示你要做处理的字段。
delimiter表示分隔符。
oby_expression_list表示要按照什么排序。
看一个例子就明白了listagg做了什么,下面这个sql列出了一个营业部所有的人员的名称,并使用逗号分隔。
SQL> SELECT DEPTNO,
2 LISTAGG(ename,',') WITHINGROUP(ORDER BY DEPTNO) enamelist
3 FROM EMP
4 GROUP BY DEPTNO;
DEPTNO ENAMELIST
------------------------------------------------------------
10CLARK,KING,MILLER
20ADAMS,FORD,JONES,SCOTT,SMITH
30ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD
FIRST/LAST Functions
语法如下:
aggregate_functionKEEP ( DENSE_RANK LAST ORDER BY
expr [ DESC | ASC ] [NULLS { FIRST |LAST }]
[, expr [ DESC | ASC ] [NULLS { FIRST |LAST }]]...)
[OVER query_partitioning_clause]
下面来看这个例子:
找出emp表中每个部门工资的最大值和最小值
SQL> SELECT DEPTNO,
2 ENAME,
3 EMPNO,
4 SAL,
5 hiredate,
6 MAX(SAL) KEEP(DENSE_RANK FIRST ORDER BY empno) OVER(PARTITION BY DEP
TNO)"min_sal",
7 MIN(SAL) KEEP(DENSE_RANK LAST ORDER BY empno) OVER(PARTITION BY DEPT
NO)"MAX_sal"
8 FROM EMP;
DEPTNO ENAME EMPNO SAL HIREDATE min_sal MAX_sal
---------- -------------------- ---------- -------------- ---------- ----------
10 CLARK 7782 2450 09-6月 -81 2450 1300
10 KING 7839 5000 17-11月-81 2450 1300
10 MILLER 7934 1300 23-1月 -82 2450 1300
20 JONES 7566 2975 02-4月 -81 10000 3000
20 FORD 7902 3000 03-12月-81 10000 3000
20 ADAMS 7876 1100 23-5月 -87 10000 3000
20 SMITH 7369 10000 17-12月-80 10000 3000
20 SCOTT 7788 3000 19-4月 -87 10000 3000
30 WARD 7521 1250 22-2月 -81 1600 950
30 TURNER 7844 1500 08-9月 -81 1600 950
30 ALLEN 7499 1600 20-2月 -81 1600 950
DEPTNO ENAME EMPNO SAL HIREDATE min_sal MAX_sal
---------- -------------------- ---------- -------------- ---------- ----------
30 JAMES 7900 950 03-12月-81 1600 950
30 BLAKE 7698 2850 01-5月 -81 1600 950
30 MARTIN 7654 1250 28-9月 -81 1600 950
一些比较好的例子
连续数问题
要求对ID相同,num连续的,查找最小num以及val求和。
表中数据如下所示:
SQL> select * fromtest_tab;
ID NUM VAL
---------- --------------------
1 1 50
1 2 100
1 3 150
1 5 250
2 1 100
2 3 400
3 1 100
3 2 200
SQL> SELECT ID,MIN(NUM), SUM(VAL)
2 FROM (SELECT ID,
3 NUM,
4 VAL,
5 NUM - ROW_NUMBER()OVER(PARTITION BY ID ORDER BY NUM) RN --使用当前值来减去rownumber
6 FROM TEST_TAB)
7 GROUP BY ID, RN
8 ORDER BY 1, 2
9 ;
ID MIN(NUM) SUM(VAL)
---------- --------------------
1 1 300
1 5 250
2 1 100
2 3 400
3 1 300
模拟SQL*PLUS BREAK 问题
SQL*PLUS提供BREAK命令,就是当前列值与前面相同,则置NULL,这是报表常用的一种手段。
SQL> break on deptno;
SQL> select deptno,empno,ename from emp wheredeptno<30 order by deptno;
DEPTNO EMPNO ENAME
---------- ---------- ----------
10 7934 MILLER
7782 CLARK
7839 KING
20 7902 FORD
7876 ADAMS
7566 JONES
7369 SMITH
7788 SCOTT
已选择8行。
SQL> SELECT DECODE(LAG(DEPTNO, 1) OVER(PARTITIONBY DEPTNO ORDER BY EMPNO),
2 DEPTNO,
3 NULL,
4 DEPTNO) deptno,
5 EMPNO,
6 ENAME
7 FROM EMP
8 WHERE deptno<30;
DEPTNO EMPNO ENAME
---------- ---------- ----------
10 7782 CLARK
7839 KING
7934 MILLER
20 7369 SMITH
7566 JONES
7788 SCOTT
7876 ADAMS
7902 FORD
重复行问题
SQL> select *from duprows;
ID NAME
--------------------
1 name
2 name
1 name
3 name
1 name
--通过以下方式找到重复行
SQL> SELECT *
2 FROM (SELECT ID,
3 NAME,
4 ROW_NUMBER() OVER(PARTITION BYB.ID ORDER BY B.ROWID) RN
5 FROM DUPROWS B) C
6 WHERE C.RN > 1;
ID NAME RN
-------------------- ----------
1 name 2
1 name 3
金额摊派问题
平均分派问题,如何将金额平均分摊,并且小数也分摊掉,避免误差
SQL> select *from demo7_1;
ID AMOUNT
--------------------
1 100
2 50
SQL> select *from demo7_2;
ID PERSONS
--------------------
1 3
2 2
SELECT ID,
PERSONS,
(CASE
WHEN RN <= (AMOUNT - AMOUNT2) * 100THEN
0.01
ELSE
0
END) + JE AS JE,
AMOUNT
--然后排序,与总金额有差额的补0.01
FROM (SELECT T.*,
SUM(JE) OVER(PARTITION BY ID) ASAMOUNT2,
ROW_NUMBER() OVER(PARTITION BYID ORDER BY JE DESC) RN
FROM (
--先展开记录数,用trunc先平均,只舍不入
SELECT TT.*
FROM (SELECT T2.ID,
T2.PERSONS,
TRUNC(T1.AMOUNT/ T2.PERSONS, 2) JE,
T1.AMOUNTAMOUNT
FROM DEMO7_1 T1,DEMO7_2 T2
WHERE T1.ID = T2.ID)TT,
--构造最大的人数序列
(SELECT LEVEL RN
FROM DUAL
CONNECT BY LEVEL <=
(SELECTMAX(PERSONS) MAX_NUM FROM DEMO7_2)) TM
WHERE TT.PERSONS >= TM.RN)T)
ID PERSONS JE AMOUNT
-------------------- ---------- ----------
1 3 33.34 100
1 3 33.33 100
1 3 33.33 100
2 2 25 50
2 2 25 50