- 浏览: 293124 次
- 性别:
- 来自: 山东-东营-利津县
文章分类
- 全部博客 (155)
- J2SE (25)
- JavaScript (8)
- Linux (4)
- Struts (12)
- Mysql (8)
- Oracle (9)
- IT与生活 (12)
- EJB (7)
- JMS (1)
- Spring (5)
- Hibernate (6)
- Jsp&Servlet (4)
- 开发小技巧 (5)
- log4j (4)
- 面试题 (20)
- DWR (2)
- JBPM (1)
- iBATIS (4)
- 数据结构 (1)
- svn (1)
- 反编译 (1)
- DB2 (4)
- Tomcat (2)
- WebService (2)
- JBoss (5)
- jquery (1)
- HttpClient (1)
- jdom (1)
- mina (1)
最新评论
-
moment52:
为什么会选择用拦截器,不用action呢
使用ThreadLocal结合struts2的拦截器实现分页 -
wzk527:
很好
编程:编写一个截取字符串的函数,(网上流传的答案有的是错的)输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4 -
shijian2292:
lz辛苦了,写的真详细,我正郁闷这些问题呢,学习了。
struts2复习笔记(version2.1.6)(01~06) -
fgh2011:
如果想要在虚拟机之外的 局域网机器中访问应用 ip需要设置成自 ...
使用secureCRT连接用VMWare虚拟机装的Linux系统 -
wangljr:
...
什么是声明式事务?什么是编程式事务?
oracle分析函数over的用法
分析函数,最早是从ORACLE8.1.6开始出现的,它的设计目的是为了解决诸如“累计计算”,“找出分组内百分比”,“前-N条查询”,“移动平均数 计算”"等问题。其实大部分的问题都可以用PL/SQL解决,但是它的性能并不能达到你所期望的效果。分析函数是SQL言语的一种扩充,它并不是仅仅试代 码变得更简单而已,它的速度比纯粹的SQL或者PL/SQL更快。现在这些扩展已经被纳入了美国国家标准化组织SQL委员会的SQL规范说明书中。
分析函数是在一个记录行分组的基础上计算它们的总值。与集合函数不同,他们返回各分组的多行记录。行的分组被称窗口,并通过分析语句定义。对于每记录行, 定义了一个“滑动”窗口。该窗口确定“当前行”计算的范围。窗口的大小可由各行的实际编号或由时间等逻辑间隔确定。
除了ORDER BY(按…排序)语句外,分析函数是一条查询被执行的操作。所有合并、WHERE、GROUP BY、HAVING语句都是分析函数处理之前完成的。因此,分析函数只出现在选择目录或ORDER BY(按…排序)语句中。
前期数据准备:
create table EMP
(
ENAME VARCHAR2(10),
DEPTNO VARCHAR2(2),
SAL NUMBER(10)
)
insert into EMP (ENAME, DEPTNO, SAL)
values ('CLARK', '10', 2450);
insert into EMP (ENAME, DEPTNO, SAL)
values ('MILLER', '10', 1300);
insert into EMP (ENAME, DEPTNO, SAL)
values ('KING', '10', 5000);
insert into EMP (ENAME, DEPTNO, SAL)
values ('FORD', '20', 3000);
insert into EMP (ENAME, DEPTNO, SAL)
values ('ADAMS', '20', 1100);
insert into EMP (ENAME, DEPTNO, SAL)
values ('JONES', '20', 2975);
insert into EMP (ENAME, DEPTNO, SAL)
values ('SCOTT ', '20', 3000);
insert into EMP (ENAME, DEPTNO, SAL)
values ('SMITH', '20', 800);
insert into EMP (ENAME, DEPTNO, SAL)
values ('ALLEN', '30', 1600);
insert into EMP (ENAME, DEPTNO, SAL)
values ('BLAKE', '30', 2850);
insert into EMP (ENAME, DEPTNO, SAL)
values ('JAMES', '30', 950);
insert into EMP (ENAME, DEPTNO, SAL)
values ('TURNER', '30', 1500);
insert into EMP (ENAME, DEPTNO, SAL)
values ('MARTIN ', '30', 1250);
insert into EMP (ENAME, DEPTNO, SAL)
values ('WARD', '30', 1250);
commit;
The Syntax句法:
OVER (
<Query-Partition-Clause>
<Order-By-Clause>
<Windowing-Clause>
)
根据划分表达式设置的规则,PARTITION BY(按…划分)将一个结果逻辑分成N个分组划分表达式。在此“划分”和“分组”用作同义词。分析函数独立应用于各个分组,并在应用时重置(按…排序)语 句规定了每个分组(划分)的数据如何排序。这必然影响分析函数的结果。
窗口生成语句用以定义滑动或固定数据窗口,分析函数在分组内进行分析。该语句能够对分组中任意定义的滑动或固定窗口进行计算。
Example: Calculate a running Total例:累计计算:本例中对某部门的工资进行逐行计算,每行包括之前所有行中工资的合计。
SELECT ename "Ename", deptno "Deptno", sal "Sal",
SUM(sal)
OVER (ORDER BY deptno, ename) "Running Total",
SUM(SAL)
OVER (PARTITION BY deptno
ORDER BY ename) "Dept Total",
ROW_NUMBER()
OVER (PARTITION BY deptno
ORDER BY ENAME) "Seq"
FROM emp
ORDER BY deptno, ename
/
Ename Deptno Sal Running Total Dept Total Seq
------ ------ ------ ------------- ---------- ----
CLARK 10 2450 2450 2450 1
KING 5000 7450 7450 2
MILLER 1300 8750 8750 3
ADAMS 20 1100 9850 1100 1
FORD 3000 12850 4100 2
JONES 2975 15825 7075 3
SCOTT 3000 18825 10075 4
SMITH 800 19625 10875 5
ALLEN 30 1600 21225 1600 1
BLAKE 2850 24075 4450 2
JAMES 950 25025 5400 3
MARTIN 1250 26275 6650 4
TURNER 1500 27775 8150 5
WARD 1250 29025 9400 6
.本例指出了如何计算整条查询的“累计”。即使用排序后的整个结果集合,通过SUM(sal) OVER (ORDER BY deptno, ename)函数得到。可以进一步计算各个部门的累计值,该值在开始下一个部门计算时将被重置。由SUM(sal)中的PARTITION BY deptno实现。该条查询中指定划分语句将数据进行分组。根据排序规则(增加了“Seq”列以显示该状态),ROW_NUMBER()函数将每组返回的 记录行进行顺序编号,执行计划显示,整条查询仅需3条一致get函数就可以很好的执行。这一点是标准SQL甚至PL/SQL不能都实现的。
Top-N Queries前N条查询:如何通过部分字段得到前N条记录?在未使用这些分析函数之前,很难对此类问题做出回答。人们关于前N条查询的说法存在问题。在 设计报告时,应留意这一点。我需要知道部门工资为前3名销售代表的谁。这句话的问题在于含混不清。因为存在重复的值,如果有四个人领着同样的工资,该怎么 处理?
Example 1例1:从多到少排列销售人员的工资,取前三行。如果该部门少于三人,则返回的记录少于三个。
SELECT * FROM (
SELECT deptno, ename, sal, ROW_NUMBER()
OVER (
PARTITION BY deptno ORDER BY sal DESC
) Top3 FROM emp
)
WHERE Top3 <= 3
/
DEPTNO ENAME SAL TOP3
---------- ---------- ---------- ----------
10 KING 5000 1
CLARK 2450 2
MILLER 1300 3
20 SCOTT 3000 1
FORD 3000 2
JONES 2975 3
30 BLAKE 2850 1
ALLEN 1600 2
TURNER 1500 3
9 rows selected.
该查询根据工资列以降序排列各个划分(或分组,属于该deptno),并在处理过程中为每行分配一个顺序号。然后使用WHERE语句得到各划分的 前三行。
Example 2例2:我需要工资为前三位的销售人员名字——即查找工资金额、排序、取最高的三项金额、给我领取这些工资的人员的名字。
SELECT * FROM (
SELECT deptno, ename, sal,
DENSE_RANK()
OVER (
PARTITION BY deptno ORDER BY sal desc
) TopN FROM emp
)
WHERE TopN <= 3
ORDER BY deptno, sal DESC
/
DEPTNO ENAME SAL TOPN
---------- ---------- ---------- ----------
10 KING 5000 1
CLARK 2450 2
MILLER 1300 3
20 SCOTT 3000 1 <--- !
FORD 3000 1 <--- !
JONES 2975 2
ADAMS 1100 3
30 BLAKE 2850 1
ALLEN 1600 2
30 TURNER 1500 3
10 rows selected.
其中,使用DENSE_RANK函数得出最高的三个工资金额。然后指定Dense rank至工资列,并将其按降序排列。 DENSE_RANK函数计算排序后分组中各行的序数。序数为从1开始的连续整数。最大的序数就是查询所所返回唯一值的个数。如果出现并列,序数不跳计。 具有相同值的列的序数相同。 DENSE_RANK函数不跳计序数,并为相同值的列赋予相同的序数。结果集合在当前窗口建立后,通过部门编号选择Dense rank为3 或3之前的行,就可以知道工资在该部门前三位的名字。
Windows窗口:
窗口语句用以定义滑动或固定数据窗口。在其上面运行组的分析函数。默认窗口为固定窗口,从第一行开始到当前行。可根据两种规则对窗口进行设置:数 据值的范围或当前行指定区距的行。分析函数中的ORDER BY会默认添加一条窗口语句:RANGE UNBOUNDED PRECEDING。即按照ORDER BY语句取得划分中的当前之前的所有行。以下例子为一个分组中的滑动窗口,计算该组中当前行与其前两行的SAL列的和。如我们需要计算当前员工的工资和其 之前的两人工资的和,如下例所示。
SELECT deptno "Deptno", ename "Ename", sal "Sal",
SUM(SAL)
OVER (PARTITION BY deptno
ORDER BY ename
ROWS 2 PRECEDING) "Sliding Total"
FROM emp
ORDER BY deptno, ename
/
Deptno Ename Sal Sliding Total
------ ------ ------ -------------
10 CLARK 2450 2450
KING 5000 7450
MILLER 1300 8750
20 ADAMS 1100 1100
FORD 3000 4100
JONES 2975 7075 ^
SCOTT 3000 8975 |
SMITH 800 6775 \-- Sliding Window
30 ALLEN 1600 1600
BLAKE 2850 4450
JAMES 950 5400
MARTIN 1250 5050
TURNER 1500 3700
WARD 1250 4000
划分语句使SUM (sal)在各部门内进行,并独立于其他组。当部门改变时,SUM (sal) 也被“重置”。ORDER BY ENAME语句通过ENAME排列各部门的数据。这使得窗口语句:ROWS 2 PRECEDING获取该分组中当前行之前两行的数据以计算合计工资。
例如,SMITH的SLIDING TOTAL(滑动合计)6 7 7 5是800、3000以及2975的和。即窗口中SMITH行及其之前两行工资的简单相加。
Range Windows范围窗口:
范围窗口根据WHERE语句对行进行收集。例如“之前5”将会生成一个滑动视窗,包括该分组中当前行之前的5个单位所有行。这些单位可以是数值或日期,使 用数字或日期以外的其他数据类型表示的范围无效。
Example例:计算当前雇佣日期之前100天内雇佣的员工的数量。范围窗口返回当前行雇佣日期100天之前并在这个范围内计算行数。计算使用 以下窗口规格:
COUNT(*) OVER (ORDER BY hiredate ASC RANGE 100 PRECEDING)
SELECT ename, hiredate, hiredate-100 hiredate_pre,
COUNT(*)
OVER (
ORDER BY hiredate ASC
RANGE 100 PRECEDING
) cnt
FROM emp
ORDER BY hiredate ASC
/
Name Hired Hired-100 Cnt
-------- ---------- ---------- ---
SMITH 17-DEC-80 08-SEP-80 1
ALLEN 20-FEB-81 12-NOV-80 2
WARD 22-FEB-81 14-NOV-80 3
JONES 02-APR-81 23-DEC-80 3
LAKE 01-MAY-81 21-JAN-81 4
CLARK 09-JUN-81 01-MAR-81 3
TURNER 08-SEP-81 31-MAY-81 2
MARTIN 28-SEP-81 20-JUN-81 2
KING 17-NOV-81 09-AUG-81 3
JAMES 03-DEC-81 25-AUG-81 5
FORD 03-DEC-81 25-AUG-81 5
MILLER 23-JAN-82 15-OCT-81 4
SCOTT 09-DEC-82 31-AUG-82 1
ADAMS 12-JAN-83 04-OCT-82 2
根据雇佣日期ASC对每个划分进行排序。例中CLARK行可看到其雇佣日期为1981年6月9日,100天之前是1981年3月1日,看看在这期间雇佣的 员工,会发现JONES(雇佣日期:1981年4月2日)、BLAKE(雇佣日期:1981年5月1日),共3行,包括当前行,在CLARK行“Cnt” 列中。
Compute average salary for defined range计算定义范围的平均工资:
,计算每个员工雇佣之前100天内雇佣员工的平均工资。查询如下:
SELECT ename, hiredate, sal,
AVG(sal)
OVER (
ORDER BY hiredate ASC
RANGE 100 PRECEDING
) avg_sal
FROM emp
ORDER BY hiredate ASC
/
Name Hired SAL Avg-100
-------- ---------- ---------- -------
SMITH 17-DEC-80 800 800
ALLEN 20-FEB-81 1600 1200
WARD 22-FEB-81 1250 1217
JONES 02-APR-81 2975 1942
BLAKE 01-MAY-81 2850 2169
CLARK 09-JUN-81 2450 2758
TURNER 08-SEP-81 1500 1975
MARTIN 28-SEP-81 1250 1375
KING 17-NOV-81 5000 2583
JAMES 03-DEC-81 950 2340
FORD 03-DEC-81 3000 2340
MILLER 23-JAN-82 1300 2563
SCOTT 09-DEC-82 3000 3000
ADAMS 12-JAN-83 1100 2050
再看看CLARK,我们已知道他在本组中的范围窗口,可以看到平均工资2758由(2975+2850+2450)/3得来,是CLARK行和其 之前的JONES和BLAKE行工资的平均数。数据必须按由小到大顺序排列。
Row Windows行窗口:
行窗口为实际单位,是包括在窗口中实际行数。例如可以计算一给定记录的平均工资,该记录包括其之前或之后雇佣的员工(至多5名),具体如下:
SELECT ename, hiredate, sal,
AVG(sal)
OVER (ORDER BY hiredate ASC ROWS 5 PRECEDING) AvgAsc,
COUNT(*)
OVER (ORDER BY hiredate ASC ROWS 5 PRECEDING) CntAsc,
AVG(sal)
OVER (ORDER BY hiredate DESC ROWS 5 PRECEDING) AvgDes,
COUNT(*)
OVER (ORDER BY hiredate DESC ROWS 5 PRECEDING) CntDes
FROM emp
ORDER BY hiredate
/
ENAME HIREDATE SAL AVGASC CNTASC AVGDES CNTDES
---------- --------- ----- ------ ------ ------ ------
SMITH 17-DEC-80 800 800 1 1988 6
ALLEN 20-FEB-81 1600 1200 2 2104 6
WARD 22-FEB-81 1250 1217 3 2046 6
JONES 02-APR-81 2975 1656 4 2671 6
BLAKE 01-MAY-81 2850 1895 5 2675 6
CLARK 09-JUN-81 2450 1988 6 2358 6
TURNER 08-SEP-81 1500 2104 6 2167 6
MARTIN 28-SEP-81 1250 2046 6 2417 6
KING 17-NOV-81 5000 2671 6 2392 6
JAMES 03-DEC-81 950 2333 6 1588 4
FORD 03-DEC-81 3000 2358 6 1870 5
MILLER 23-JAN-82 1300 2167 6 1800 3
SCOTT 09-DEC-82 3000 2417 6 2050 2
ADAMS 12-JAN-83 1100 2392 6 1100 1
.该窗口中包括6行,现有行及此行“之前”的5行,其中“之前”由ORDER BY语句定义。对于ROW(行)的划分,不受RANGE(范围)划分的限制——数据可以是任何类型,order by可包括许多列。注意,也要选择COUNT(*),可以说明是多少行的平均值。从ALLEN记录可以清楚看到,他之前雇佣员工平均工资的计算使用了2个 记录,他之后雇佣员工平均工资的计算使用了6个记录。
LAG(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) last_hire,
hiredate - LAG(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) days_last,
LEAD(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) next_hire,
LEAD(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) - hiredate days_next
FROM emp
ORDER BY deptno, hiredate
/
Dep Ename Hired LastHired DaysLast NextHire NextDays
--- ------ --------- --------- -------- --------- --------
10 CLARK 09-JUN-81 17-NOV-81 161
KING 17-NOV-81 09-JUN-81 161 23-JAN-82 67
MILLER 23-JAN-82 17-NOV-81 67
20 SMITH 17-DEC-80 02-APR-81 106
JONES 02-APR-81 17-DEC-80 106 03-DEC-81 245
FORD 03-DEC-81 02-APR-81 245 09-DEC-82 371
SCOTT 09-DEC-82 03-DEC-81 371 12-JAN-83 34
ADAMS 12-JAN-83 09-DEC-82 34
30 ALLEN 20-FEB-81 22-FEB-81 2
WARD 22-FEB-81 20-FEB-81 2 01-MAY-81 68
BLAKE 01-MAY-81 22-FEB-81 68 08-SEP-81 130
TURNER 08-SEP-81 01-MAY-81 130 28-SEP-81 20
MARTIN 28-SEP-81 08-SEP-81 20 03-DEC-81 66
JAMES 03-DEC-81 28-SEP-81 66
LEAD和LAG例程可看作对分组进行索引。使用这些函数可以访问任何一行。上面例子表明KING记录包括之前一行(上一雇佣)和下一行(下一) 中的数据(加粗红色字体)。可以很容易的访问排序后的分组中当前记录之前或之后记录中的字段。
LAG
LAG ( value_expr [, offset] [, default] )
OVER ( [query_partition_clause] order_by_clause )
. LAG无须自合并就可以获取同一个表格中的多行记录。知道来自查询中的多行以及光标的位置,LEAD就可以进入位置指定区距之前的行。
如果不指定区距,默认值为1。如果区距超出窗口范围,则返回可指定默认值。如不指定默认值,则默认值为null。
EMP表中的每个人之前雇佣员工的:
SELECT ename,hiredate,sal,
LAG(sal, 1, 0)
OVER (ORDER BY hiredate) AS PrevSal
FROM emp
WHERE job = 'CLERK';
Ename Hired SAL PREVSAL
------ --------- ----- -------
SMITH 17-DEC-80 800 0
JAMES 03-DEC-81 950 800
MILLER 23-JAN-82 1300 950
ADAMS 12-JAN-83 1100 1300
LEAD
LEAD ( value_expr [, offset] [, default] )
OVER ( [query_partition_clause] order_by_clause )
LEAD不用自合并就可同时进入一个表格中的多行。知道来自查询中的多行以及光标的位置,LEAD就可以进入位置指定区距之后的行。
如不指定区距,则默认值为1。如区距超出窗口范围则返回任意默认值。如不指定默认值,默认值为0。
例,EMP表中的每个员工,他们之后雇佣员工的雇佣日期:
SELECT ename, hiredate,
LEAD(hiredate, 1)
OVER (ORDER BY hiredate) AS NextHired
FROM emp WHERE deptno = 30;
Ename Hired NEXTHIRED
------ --------- ---------
ALLEN 20-FEB-81 22-FEB-81
WARD 22-FEB-81 01-MAY-81
BLAKE 01-MAY-81 08-SEP-81
TURNER 08-SEP-81 28-SEP-81
MARTIN 28-SEP-81 03-DEC-81
JAMES 03-DEC-81
Determine the First Value / Last Value of a Group确定组中的第一个值/最后一个值:
FIRST_VALUE与LAST_VALUE函数可以选择一组中的第一行和最后一行。这些行很有用,因为它们经常用作计算的基线。
Example例:例为每个部门的每名员工、最高工资员工的姓名。
SELECT deptno, ename, sal,
FIRST_VALUE(ename)
OVER (PARTITION BY deptno
ORDER BY sal ASC) AS MIN_SAL_HAS
FROM emp
ORDER BY deptno, ename;
DEPTNO ENAME SAL MIN_SAL_HAS
---------- ---------- ---------- -----------
10 CLARK 2450 MILLER
KING 5000 MILLER
MILLER 1300 MILLER
20 ADAMS 1100 SMITH
FORD 3000 SMITH
JONES 2975 SMITH
SCOTT 3000 SMITH
SMITH 800 SMITH
30 ALLEN 1600 JAMES
BLAKE 2850 JAMES
JAMES 950 JAMES
MARTIN 1250 JAMES
TURNER 1500 JAMES
WARD 1250 JAMES
下例中为每个部门的每名员工、最高工资员工的姓名。
SELECT deptno, ename, sal,
FIRST_VALUE(ename)
OVER (PARTITION BY deptno
ORDER BY sal DESC) AS MAX_SAL_HAS
FROM emp
ORDER BY deptno, ename;
DEPTNO ENAME SAL MAX_SAL_HAS
---------- ---------- ---------- -----_-----
10 CLARK 2450 KING
KING 5000 KING
MILLER 1300 KING
20 ADAMS 1100 FORD
FORD 3000 FORD
JONES 2975 FORD
SCOTT 3000 FORD
SMITH 800 FORD
30 ALLEN 1600 BLAKE
BLAKE 2850 BLAKE
JAMES 950 BLAKE
MARTIN 1250 BLAKE
TURNER 1500 BLAKE
WARD 1250 BLAKE
下例为第30个部门中的每名员工、工资最低员工的姓名,使用内联视图。
SELECT deptno, ename, sal,
FIRST_VALUE(ename)
OVER (ORDER BY sal ASC) AS MIN_SAL_HAS
FROM (SELECT * FROM emp WHERE deptno = 30)
DEPTNO ENAME SAL MIN_SAL_HAS
---------- ---------- ---------- -----------
30 JAMES 950 JAMES
MARTIN 1250 JAMES
WARD 1250 JAMES
TURNER 1500 JAMES
ALLEN 1600 JAMES
BLAKE 2850 JAMES
交叉表查询,或者pivot查询,用稍微不同的方法将这些数据分组。交叉表查询可根据三行(一行代表一个项目),每行有三列(第一列列出项目,然 后一列代表一年)得出结果——如下:
Example例:
如果需要以列的形式显示每个部门中工资最多的3个人,查询为每个部门返回一行,一行有4列。DEPTNO,该部门中工资最高的人,工资第二高人的 名字,依次类推。使用分析函数很容易做到,不采用有分析函数这将是不可能的。
SELECT deptno,
MAX(DECODE(seq,1,ename,null)) first,
MAX(DECODE(seq,2,ename,null)) second,
MAX(DECODE(seq,3,ename,null)) third
FROM (SELECT deptno, ename,
row_number()
OVER (PARTITION BY deptno
ORDER BY sal desc NULLS LAST) seq
FROM emp)
WHERE seq <= 3
GROUP BY deptno
/
DEPTNO FIRST SECOND THIRD
---------- ---------- ---------- ----------
10 KING CLARK MILLER
20 SCOTT FORD JONES
30 BLAKE ALLEN TURNER
注意内查询,它按照工资高低根据部门为每名员工赋予一个序列(RowNr)。
SELECT deptno, ename, sal,
row_number()
OVER (PARTITION BY deptno
ORDER BY sal desc NULLS LAST) RowNr
FROM emp;
DEPTNO ENAME SAL ROWNR
---------- ---------- ---------- ----------
10 KING 5000 1
10 CLARK 2450 2
10 MILLER 1300 3
20 SCOTT 3000 1
20 FORD 3000 2
20 JONES 2975 3
20 ADAMS 1100 4
20 SMITH 800 5
30 BLAKE 2850 1
30 ALLEN 1600 2
30 TURNER 1500 3
30 WARD 1250 4
30 MARTIN 1250 5
30 JAMES 950 6
外查询中DECODE只保留含有序列1、2或3的记录行,并将它们分派到正确的“列”。GROUP BY去掉多余行,只剩下压缩结果。如果没有根据deptno分组的合计函数MAX,结果会更容易理解。
SELECT deptno,
DECODE(seq,1,ename,null) first,
DECODE(seq,2,ename,null) second,
DECODE(seq,3,ename,null) third
FROM (SELECT deptno, ename,
row_number()
OVER (PARTITION BY deptno
ORDER BY sal desc NULLS LAST) seq
FROM emp)
WHERE seq <= 3
/
DEPTNO FIRST SECOND THIRD
---------- ---------- ---------- ----------
10 KING
10 CLARK
10 MILLER
20 SCOTT
20 FORD
20 JONES
30 BLAKE
30 ALLEN
30 TURNER
通过GROUP BY列DEPTNO(按DEPTNO分组列)应用MAX合计函数。在上面任意给出的DEPTNO中,只有一行将对FIRST有非null值,其余行将永远 是NULL。MAX函数将选出非NULL值并保存。因此,group by和MAX将会压缩结果集,去掉NULL值并给出我们想要的值。
分析函数,最早是从ORACLE8.1.6开始出现的,它的设计目的是为了解决诸如“累计计算”,“找出分组内百分比”,“前-N条查询”,“移动平均数 计算”"等问题。其实大部分的问题都可以用PL/SQL解决,但是它的性能并不能达到你所期望的效果。分析函数是SQL言语的一种扩充,它并不是仅仅试代 码变得更简单而已,它的速度比纯粹的SQL或者PL/SQL更快。现在这些扩展已经被纳入了美国国家标准化组织SQL委员会的SQL规范说明书中。
分析函数是在一个记录行分组的基础上计算它们的总值。与集合函数不同,他们返回各分组的多行记录。行的分组被称窗口,并通过分析语句定义。对于每记录行, 定义了一个“滑动”窗口。该窗口确定“当前行”计算的范围。窗口的大小可由各行的实际编号或由时间等逻辑间隔确定。
除了ORDER BY(按…排序)语句外,分析函数是一条查询被执行的操作。所有合并、WHERE、GROUP BY、HAVING语句都是分析函数处理之前完成的。因此,分析函数只出现在选择目录或ORDER BY(按…排序)语句中。
前期数据准备:
create table EMP
(
ENAME VARCHAR2(10),
DEPTNO VARCHAR2(2),
SAL NUMBER(10)
)
insert into EMP (ENAME, DEPTNO, SAL)
values ('CLARK', '10', 2450);
insert into EMP (ENAME, DEPTNO, SAL)
values ('MILLER', '10', 1300);
insert into EMP (ENAME, DEPTNO, SAL)
values ('KING', '10', 5000);
insert into EMP (ENAME, DEPTNO, SAL)
values ('FORD', '20', 3000);
insert into EMP (ENAME, DEPTNO, SAL)
values ('ADAMS', '20', 1100);
insert into EMP (ENAME, DEPTNO, SAL)
values ('JONES', '20', 2975);
insert into EMP (ENAME, DEPTNO, SAL)
values ('SCOTT ', '20', 3000);
insert into EMP (ENAME, DEPTNO, SAL)
values ('SMITH', '20', 800);
insert into EMP (ENAME, DEPTNO, SAL)
values ('ALLEN', '30', 1600);
insert into EMP (ENAME, DEPTNO, SAL)
values ('BLAKE', '30', 2850);
insert into EMP (ENAME, DEPTNO, SAL)
values ('JAMES', '30', 950);
insert into EMP (ENAME, DEPTNO, SAL)
values ('TURNER', '30', 1500);
insert into EMP (ENAME, DEPTNO, SAL)
values ('MARTIN ', '30', 1250);
insert into EMP (ENAME, DEPTNO, SAL)
values ('WARD', '30', 1250);
commit;
The Syntax句法:
OVER (
<Query-Partition-Clause>
<Order-By-Clause>
<Windowing-Clause>
)
根据划分表达式设置的规则,PARTITION BY(按…划分)将一个结果逻辑分成N个分组划分表达式。在此“划分”和“分组”用作同义词。分析函数独立应用于各个分组,并在应用时重置(按…排序)语 句规定了每个分组(划分)的数据如何排序。这必然影响分析函数的结果。
窗口生成语句用以定义滑动或固定数据窗口,分析函数在分组内进行分析。该语句能够对分组中任意定义的滑动或固定窗口进行计算。
Example: Calculate a running Total例:累计计算:本例中对某部门的工资进行逐行计算,每行包括之前所有行中工资的合计。
SELECT ename "Ename", deptno "Deptno", sal "Sal",
SUM(sal)
OVER (ORDER BY deptno, ename) "Running Total",
SUM(SAL)
OVER (PARTITION BY deptno
ORDER BY ename) "Dept Total",
ROW_NUMBER()
OVER (PARTITION BY deptno
ORDER BY ENAME) "Seq"
FROM emp
ORDER BY deptno, ename
/
Ename Deptno Sal Running Total Dept Total Seq
------ ------ ------ ------------- ---------- ----
CLARK 10 2450 2450 2450 1
KING 5000 7450 7450 2
MILLER 1300 8750 8750 3
ADAMS 20 1100 9850 1100 1
FORD 3000 12850 4100 2
JONES 2975 15825 7075 3
SCOTT 3000 18825 10075 4
SMITH 800 19625 10875 5
ALLEN 30 1600 21225 1600 1
BLAKE 2850 24075 4450 2
JAMES 950 25025 5400 3
MARTIN 1250 26275 6650 4
TURNER 1500 27775 8150 5
WARD 1250 29025 9400 6
.本例指出了如何计算整条查询的“累计”。即使用排序后的整个结果集合,通过SUM(sal) OVER (ORDER BY deptno, ename)函数得到。可以进一步计算各个部门的累计值,该值在开始下一个部门计算时将被重置。由SUM(sal)中的PARTITION BY deptno实现。该条查询中指定划分语句将数据进行分组。根据排序规则(增加了“Seq”列以显示该状态),ROW_NUMBER()函数将每组返回的 记录行进行顺序编号,执行计划显示,整条查询仅需3条一致get函数就可以很好的执行。这一点是标准SQL甚至PL/SQL不能都实现的。
Top-N Queries前N条查询:如何通过部分字段得到前N条记录?在未使用这些分析函数之前,很难对此类问题做出回答。人们关于前N条查询的说法存在问题。在 设计报告时,应留意这一点。我需要知道部门工资为前3名销售代表的谁。这句话的问题在于含混不清。因为存在重复的值,如果有四个人领着同样的工资,该怎么 处理?
Example 1例1:从多到少排列销售人员的工资,取前三行。如果该部门少于三人,则返回的记录少于三个。
SELECT * FROM (
SELECT deptno, ename, sal, ROW_NUMBER()
OVER (
PARTITION BY deptno ORDER BY sal DESC
) Top3 FROM emp
)
WHERE Top3 <= 3
/
DEPTNO ENAME SAL TOP3
---------- ---------- ---------- ----------
10 KING 5000 1
CLARK 2450 2
MILLER 1300 3
20 SCOTT 3000 1
FORD 3000 2
JONES 2975 3
30 BLAKE 2850 1
ALLEN 1600 2
TURNER 1500 3
9 rows selected.
该查询根据工资列以降序排列各个划分(或分组,属于该deptno),并在处理过程中为每行分配一个顺序号。然后使用WHERE语句得到各划分的 前三行。
Example 2例2:我需要工资为前三位的销售人员名字——即查找工资金额、排序、取最高的三项金额、给我领取这些工资的人员的名字。
SELECT * FROM (
SELECT deptno, ename, sal,
DENSE_RANK()
OVER (
PARTITION BY deptno ORDER BY sal desc
) TopN FROM emp
)
WHERE TopN <= 3
ORDER BY deptno, sal DESC
/
DEPTNO ENAME SAL TOPN
---------- ---------- ---------- ----------
10 KING 5000 1
CLARK 2450 2
MILLER 1300 3
20 SCOTT 3000 1 <--- !
FORD 3000 1 <--- !
JONES 2975 2
ADAMS 1100 3
30 BLAKE 2850 1
ALLEN 1600 2
30 TURNER 1500 3
10 rows selected.
其中,使用DENSE_RANK函数得出最高的三个工资金额。然后指定Dense rank至工资列,并将其按降序排列。 DENSE_RANK函数计算排序后分组中各行的序数。序数为从1开始的连续整数。最大的序数就是查询所所返回唯一值的个数。如果出现并列,序数不跳计。 具有相同值的列的序数相同。 DENSE_RANK函数不跳计序数,并为相同值的列赋予相同的序数。结果集合在当前窗口建立后,通过部门编号选择Dense rank为3 或3之前的行,就可以知道工资在该部门前三位的名字。
Windows窗口:
窗口语句用以定义滑动或固定数据窗口。在其上面运行组的分析函数。默认窗口为固定窗口,从第一行开始到当前行。可根据两种规则对窗口进行设置:数 据值的范围或当前行指定区距的行。分析函数中的ORDER BY会默认添加一条窗口语句:RANGE UNBOUNDED PRECEDING。即按照ORDER BY语句取得划分中的当前之前的所有行。以下例子为一个分组中的滑动窗口,计算该组中当前行与其前两行的SAL列的和。如我们需要计算当前员工的工资和其 之前的两人工资的和,如下例所示。
SELECT deptno "Deptno", ename "Ename", sal "Sal",
SUM(SAL)
OVER (PARTITION BY deptno
ORDER BY ename
ROWS 2 PRECEDING) "Sliding Total"
FROM emp
ORDER BY deptno, ename
/
Deptno Ename Sal Sliding Total
------ ------ ------ -------------
10 CLARK 2450 2450
KING 5000 7450
MILLER 1300 8750
20 ADAMS 1100 1100
FORD 3000 4100
JONES 2975 7075 ^
SCOTT 3000 8975 |
SMITH 800 6775 \-- Sliding Window
30 ALLEN 1600 1600
BLAKE 2850 4450
JAMES 950 5400
MARTIN 1250 5050
TURNER 1500 3700
WARD 1250 4000
划分语句使SUM (sal)在各部门内进行,并独立于其他组。当部门改变时,SUM (sal) 也被“重置”。ORDER BY ENAME语句通过ENAME排列各部门的数据。这使得窗口语句:ROWS 2 PRECEDING获取该分组中当前行之前两行的数据以计算合计工资。
例如,SMITH的SLIDING TOTAL(滑动合计)6 7 7 5是800、3000以及2975的和。即窗口中SMITH行及其之前两行工资的简单相加。
Range Windows范围窗口:
范围窗口根据WHERE语句对行进行收集。例如“之前5”将会生成一个滑动视窗,包括该分组中当前行之前的5个单位所有行。这些单位可以是数值或日期,使 用数字或日期以外的其他数据类型表示的范围无效。
Example例:计算当前雇佣日期之前100天内雇佣的员工的数量。范围窗口返回当前行雇佣日期100天之前并在这个范围内计算行数。计算使用 以下窗口规格:
COUNT(*) OVER (ORDER BY hiredate ASC RANGE 100 PRECEDING)
SELECT ename, hiredate, hiredate-100 hiredate_pre,
COUNT(*)
OVER (
ORDER BY hiredate ASC
RANGE 100 PRECEDING
) cnt
FROM emp
ORDER BY hiredate ASC
/
Name Hired Hired-100 Cnt
-------- ---------- ---------- ---
SMITH 17-DEC-80 08-SEP-80 1
ALLEN 20-FEB-81 12-NOV-80 2
WARD 22-FEB-81 14-NOV-80 3
JONES 02-APR-81 23-DEC-80 3
LAKE 01-MAY-81 21-JAN-81 4
CLARK 09-JUN-81 01-MAR-81 3
TURNER 08-SEP-81 31-MAY-81 2
MARTIN 28-SEP-81 20-JUN-81 2
KING 17-NOV-81 09-AUG-81 3
JAMES 03-DEC-81 25-AUG-81 5
FORD 03-DEC-81 25-AUG-81 5
MILLER 23-JAN-82 15-OCT-81 4
SCOTT 09-DEC-82 31-AUG-82 1
ADAMS 12-JAN-83 04-OCT-82 2
根据雇佣日期ASC对每个划分进行排序。例中CLARK行可看到其雇佣日期为1981年6月9日,100天之前是1981年3月1日,看看在这期间雇佣的 员工,会发现JONES(雇佣日期:1981年4月2日)、BLAKE(雇佣日期:1981年5月1日),共3行,包括当前行,在CLARK行“Cnt” 列中。
Compute average salary for defined range计算定义范围的平均工资:
,计算每个员工雇佣之前100天内雇佣员工的平均工资。查询如下:
SELECT ename, hiredate, sal,
AVG(sal)
OVER (
ORDER BY hiredate ASC
RANGE 100 PRECEDING
) avg_sal
FROM emp
ORDER BY hiredate ASC
/
Name Hired SAL Avg-100
-------- ---------- ---------- -------
SMITH 17-DEC-80 800 800
ALLEN 20-FEB-81 1600 1200
WARD 22-FEB-81 1250 1217
JONES 02-APR-81 2975 1942
BLAKE 01-MAY-81 2850 2169
CLARK 09-JUN-81 2450 2758
TURNER 08-SEP-81 1500 1975
MARTIN 28-SEP-81 1250 1375
KING 17-NOV-81 5000 2583
JAMES 03-DEC-81 950 2340
FORD 03-DEC-81 3000 2340
MILLER 23-JAN-82 1300 2563
SCOTT 09-DEC-82 3000 3000
ADAMS 12-JAN-83 1100 2050
再看看CLARK,我们已知道他在本组中的范围窗口,可以看到平均工资2758由(2975+2850+2450)/3得来,是CLARK行和其 之前的JONES和BLAKE行工资的平均数。数据必须按由小到大顺序排列。
Row Windows行窗口:
行窗口为实际单位,是包括在窗口中实际行数。例如可以计算一给定记录的平均工资,该记录包括其之前或之后雇佣的员工(至多5名),具体如下:
SELECT ename, hiredate, sal,
AVG(sal)
OVER (ORDER BY hiredate ASC ROWS 5 PRECEDING) AvgAsc,
COUNT(*)
OVER (ORDER BY hiredate ASC ROWS 5 PRECEDING) CntAsc,
AVG(sal)
OVER (ORDER BY hiredate DESC ROWS 5 PRECEDING) AvgDes,
COUNT(*)
OVER (ORDER BY hiredate DESC ROWS 5 PRECEDING) CntDes
FROM emp
ORDER BY hiredate
/
ENAME HIREDATE SAL AVGASC CNTASC AVGDES CNTDES
---------- --------- ----- ------ ------ ------ ------
SMITH 17-DEC-80 800 800 1 1988 6
ALLEN 20-FEB-81 1600 1200 2 2104 6
WARD 22-FEB-81 1250 1217 3 2046 6
JONES 02-APR-81 2975 1656 4 2671 6
BLAKE 01-MAY-81 2850 1895 5 2675 6
CLARK 09-JUN-81 2450 1988 6 2358 6
TURNER 08-SEP-81 1500 2104 6 2167 6
MARTIN 28-SEP-81 1250 2046 6 2417 6
KING 17-NOV-81 5000 2671 6 2392 6
JAMES 03-DEC-81 950 2333 6 1588 4
FORD 03-DEC-81 3000 2358 6 1870 5
MILLER 23-JAN-82 1300 2167 6 1800 3
SCOTT 09-DEC-82 3000 2417 6 2050 2
ADAMS 12-JAN-83 1100 2392 6 1100 1
.该窗口中包括6行,现有行及此行“之前”的5行,其中“之前”由ORDER BY语句定义。对于ROW(行)的划分,不受RANGE(范围)划分的限制——数据可以是任何类型,order by可包括许多列。注意,也要选择COUNT(*),可以说明是多少行的平均值。从ALLEN记录可以清楚看到,他之前雇佣员工平均工资的计算使用了2个 记录,他之后雇佣员工平均工资的计算使用了6个记录。
LAG(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) last_hire,
hiredate - LAG(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) days_last,
LEAD(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) next_hire,
LEAD(hiredate,1,NULL)
OVER (PARTITION BY deptno
ORDER BY hiredate, ename) - hiredate days_next
FROM emp
ORDER BY deptno, hiredate
/
Dep Ename Hired LastHired DaysLast NextHire NextDays
--- ------ --------- --------- -------- --------- --------
10 CLARK 09-JUN-81 17-NOV-81 161
KING 17-NOV-81 09-JUN-81 161 23-JAN-82 67
MILLER 23-JAN-82 17-NOV-81 67
20 SMITH 17-DEC-80 02-APR-81 106
JONES 02-APR-81 17-DEC-80 106 03-DEC-81 245
FORD 03-DEC-81 02-APR-81 245 09-DEC-82 371
SCOTT 09-DEC-82 03-DEC-81 371 12-JAN-83 34
ADAMS 12-JAN-83 09-DEC-82 34
30 ALLEN 20-FEB-81 22-FEB-81 2
WARD 22-FEB-81 20-FEB-81 2 01-MAY-81 68
BLAKE 01-MAY-81 22-FEB-81 68 08-SEP-81 130
TURNER 08-SEP-81 01-MAY-81 130 28-SEP-81 20
MARTIN 28-SEP-81 08-SEP-81 20 03-DEC-81 66
JAMES 03-DEC-81 28-SEP-81 66
LEAD和LAG例程可看作对分组进行索引。使用这些函数可以访问任何一行。上面例子表明KING记录包括之前一行(上一雇佣)和下一行(下一) 中的数据(加粗红色字体)。可以很容易的访问排序后的分组中当前记录之前或之后记录中的字段。
LAG
LAG ( value_expr [, offset] [, default] )
OVER ( [query_partition_clause] order_by_clause )
. LAG无须自合并就可以获取同一个表格中的多行记录。知道来自查询中的多行以及光标的位置,LEAD就可以进入位置指定区距之前的行。
如果不指定区距,默认值为1。如果区距超出窗口范围,则返回可指定默认值。如不指定默认值,则默认值为null。
EMP表中的每个人之前雇佣员工的:
SELECT ename,hiredate,sal,
LAG(sal, 1, 0)
OVER (ORDER BY hiredate) AS PrevSal
FROM emp
WHERE job = 'CLERK';
Ename Hired SAL PREVSAL
------ --------- ----- -------
SMITH 17-DEC-80 800 0
JAMES 03-DEC-81 950 800
MILLER 23-JAN-82 1300 950
ADAMS 12-JAN-83 1100 1300
LEAD
LEAD ( value_expr [, offset] [, default] )
OVER ( [query_partition_clause] order_by_clause )
LEAD不用自合并就可同时进入一个表格中的多行。知道来自查询中的多行以及光标的位置,LEAD就可以进入位置指定区距之后的行。
如不指定区距,则默认值为1。如区距超出窗口范围则返回任意默认值。如不指定默认值,默认值为0。
例,EMP表中的每个员工,他们之后雇佣员工的雇佣日期:
SELECT ename, hiredate,
LEAD(hiredate, 1)
OVER (ORDER BY hiredate) AS NextHired
FROM emp WHERE deptno = 30;
Ename Hired NEXTHIRED
------ --------- ---------
ALLEN 20-FEB-81 22-FEB-81
WARD 22-FEB-81 01-MAY-81
BLAKE 01-MAY-81 08-SEP-81
TURNER 08-SEP-81 28-SEP-81
MARTIN 28-SEP-81 03-DEC-81
JAMES 03-DEC-81
Determine the First Value / Last Value of a Group确定组中的第一个值/最后一个值:
FIRST_VALUE与LAST_VALUE函数可以选择一组中的第一行和最后一行。这些行很有用,因为它们经常用作计算的基线。
Example例:例为每个部门的每名员工、最高工资员工的姓名。
SELECT deptno, ename, sal,
FIRST_VALUE(ename)
OVER (PARTITION BY deptno
ORDER BY sal ASC) AS MIN_SAL_HAS
FROM emp
ORDER BY deptno, ename;
DEPTNO ENAME SAL MIN_SAL_HAS
---------- ---------- ---------- -----------
10 CLARK 2450 MILLER
KING 5000 MILLER
MILLER 1300 MILLER
20 ADAMS 1100 SMITH
FORD 3000 SMITH
JONES 2975 SMITH
SCOTT 3000 SMITH
SMITH 800 SMITH
30 ALLEN 1600 JAMES
BLAKE 2850 JAMES
JAMES 950 JAMES
MARTIN 1250 JAMES
TURNER 1500 JAMES
WARD 1250 JAMES
下例中为每个部门的每名员工、最高工资员工的姓名。
SELECT deptno, ename, sal,
FIRST_VALUE(ename)
OVER (PARTITION BY deptno
ORDER BY sal DESC) AS MAX_SAL_HAS
FROM emp
ORDER BY deptno, ename;
DEPTNO ENAME SAL MAX_SAL_HAS
---------- ---------- ---------- -----_-----
10 CLARK 2450 KING
KING 5000 KING
MILLER 1300 KING
20 ADAMS 1100 FORD
FORD 3000 FORD
JONES 2975 FORD
SCOTT 3000 FORD
SMITH 800 FORD
30 ALLEN 1600 BLAKE
BLAKE 2850 BLAKE
JAMES 950 BLAKE
MARTIN 1250 BLAKE
TURNER 1500 BLAKE
WARD 1250 BLAKE
下例为第30个部门中的每名员工、工资最低员工的姓名,使用内联视图。
SELECT deptno, ename, sal,
FIRST_VALUE(ename)
OVER (ORDER BY sal ASC) AS MIN_SAL_HAS
FROM (SELECT * FROM emp WHERE deptno = 30)
DEPTNO ENAME SAL MIN_SAL_HAS
---------- ---------- ---------- -----------
30 JAMES 950 JAMES
MARTIN 1250 JAMES
WARD 1250 JAMES
TURNER 1500 JAMES
ALLEN 1600 JAMES
BLAKE 2850 JAMES
交叉表查询,或者pivot查询,用稍微不同的方法将这些数据分组。交叉表查询可根据三行(一行代表一个项目),每行有三列(第一列列出项目,然 后一列代表一年)得出结果——如下:
Example例:
如果需要以列的形式显示每个部门中工资最多的3个人,查询为每个部门返回一行,一行有4列。DEPTNO,该部门中工资最高的人,工资第二高人的 名字,依次类推。使用分析函数很容易做到,不采用有分析函数这将是不可能的。
SELECT deptno,
MAX(DECODE(seq,1,ename,null)) first,
MAX(DECODE(seq,2,ename,null)) second,
MAX(DECODE(seq,3,ename,null)) third
FROM (SELECT deptno, ename,
row_number()
OVER (PARTITION BY deptno
ORDER BY sal desc NULLS LAST) seq
FROM emp)
WHERE seq <= 3
GROUP BY deptno
/
DEPTNO FIRST SECOND THIRD
---------- ---------- ---------- ----------
10 KING CLARK MILLER
20 SCOTT FORD JONES
30 BLAKE ALLEN TURNER
注意内查询,它按照工资高低根据部门为每名员工赋予一个序列(RowNr)。
SELECT deptno, ename, sal,
row_number()
OVER (PARTITION BY deptno
ORDER BY sal desc NULLS LAST) RowNr
FROM emp;
DEPTNO ENAME SAL ROWNR
---------- ---------- ---------- ----------
10 KING 5000 1
10 CLARK 2450 2
10 MILLER 1300 3
20 SCOTT 3000 1
20 FORD 3000 2
20 JONES 2975 3
20 ADAMS 1100 4
20 SMITH 800 5
30 BLAKE 2850 1
30 ALLEN 1600 2
30 TURNER 1500 3
30 WARD 1250 4
30 MARTIN 1250 5
30 JAMES 950 6
外查询中DECODE只保留含有序列1、2或3的记录行,并将它们分派到正确的“列”。GROUP BY去掉多余行,只剩下压缩结果。如果没有根据deptno分组的合计函数MAX,结果会更容易理解。
SELECT deptno,
DECODE(seq,1,ename,null) first,
DECODE(seq,2,ename,null) second,
DECODE(seq,3,ename,null) third
FROM (SELECT deptno, ename,
row_number()
OVER (PARTITION BY deptno
ORDER BY sal desc NULLS LAST) seq
FROM emp)
WHERE seq <= 3
/
DEPTNO FIRST SECOND THIRD
---------- ---------- ---------- ----------
10 KING
10 CLARK
10 MILLER
20 SCOTT
20 FORD
20 JONES
30 BLAKE
30 ALLEN
30 TURNER
通过GROUP BY列DEPTNO(按DEPTNO分组列)应用MAX合计函数。在上面任意给出的DEPTNO中,只有一行将对FIRST有非null值,其余行将永远 是NULL。MAX函数将选出非NULL值并保存。因此,group by和MAX将会压缩结果集,去掉NULL值并给出我们想要的值。
发表评论
-
Oracle 分析函数partition by order by 产生并列的情况
2012-04-16 13:40 0以Oracle数据库scott用户下自带的几张测试表说明如下问 ... -
使用pl/sql连接远程Oracle服务器
2012-04-13 14:00 14981、首先需要在Oracle服务器端需要配置一个监听器用来监听客 ... -
Oralce笔记02
2011-09-03 16:36 98422、什么是索引 (1)一种能够提供查询效率的数据库对象 ... -
Oralce笔记01
2011-08-06 11:58 10371、使用子查询创建表 (1)指定要创建表的字段 c ... -
Oralce的简单的导入导出命令
2011-07-04 22:18 877转载 一、数据导出: ... -
利用Oracle客户端工具PL / SQL Developer- 比较用户对象
2011-06-08 14:07 1923在实际的项目实施过程中,由测试转到生产时,为了确保测试时使用的 ... -
"OracleOraDb10g_Home1TNSListener服务启动后又停止了。一些服务自动停止,如果它们没有什么可做的“性能日志和警报”"问题解决办法
2011-04-22 16:51 2654[问题]出现这个问题应该是listener.ora 里面配置的 ... -
oracle表空间的创建、删除、查看、表空间不存在、及修改默认表空间详解(转)
2010-05-26 16:30 5221一.创建表空间 ORACLE中 ... -
尚学堂马士兵Oracle教程 笔记
2010-03-02 21:09 1948首先,以超级管理员的身份登录oracle sqlpl ...
相关推荐
基于java的校园美食交流系统设计与实现.docx
均包含代码,文章,部分项目包含ppt
基于python的酒店评论中文情感分析系统源码+设计文档+数据集.zip基于python的酒店评论中文情感分析系统源码+设计文档+数据集.zip基于python的酒店评论中文情感分析系统源码+设计文档+数据集.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.m或d论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 、1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
基于Django框架开发的协同过滤算法小说推荐系统是一种利用用户行为数据来提供个性化小说推荐的应用。该系统通过分析用户的历史阅读记录、评分和反馈,发现用户之间的相似性或小说之间的相似性,进而为用户推荐可能感兴趣的小说。以下是该系统可能包含的关键特性: 1. **用户账户管理**:允许用户创建账户、登录和编辑个人信息,同时跟踪用户的阅读历史和评分。 2. **小说数据库**:构建一个包含大量小说信息的数据库,每本小说都有详细的元数据,如作者、出版年份、流派、标签等。 3. **协同过滤引擎**:实现协同过滤算法,包括用户-用户协同过滤和项目-项目协同过滤,以发现相似用户或相似小说。 4. **推荐生成**:根据协同过滤引擎的结果,生成个性化的小说推荐列表,并提供给用户。 5. **评分系统**:允许用户对小说进行评分,这些评分数据将用于训练推荐算法,提高推荐的准确性。 6. **用户界面**:设计直观、易用的用户界面,使用户能够轻松浏览推荐的小说、查看详情和进行评分。 7. **搜索和筛选功能**:提供强大的搜索功能,允许用户根据标题、作者或流派等关键词搜索小说,并提供筛选
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资源 5来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。、资 5源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
内容概要:本文是关于2020年度数字孪生技术的最新进展和发展趋势的研究报告。文中对数字孪生技术及其应用场景作出了详细的阐述,特别强调了数字孪生在智能制造、智慧城市、产品开发等多个领域内的实际应用成果,并讨论了数字孪生带来的信息安全方面的挑战和解决方案。 适用人群:面向希望深入了解和应用数字孪生技术的企业管理人员、研发工程师和学者。 使用场景及目标:适用于企业或机构寻求改进产品设计、生产制造、城市管理等领域效能的情况,助力相关人员理解和实现更加精细的管理决策和模拟预测,进而优化资源配置与提升工作效率。 其它说明:介绍了多项核心技术,包括但不限于数据收集、建模仿真、模型管理系统等,并分享了多个数字孪生的真实应用案例以展示其实效。
基于java的的德云社票务系统的设计与实现.docx
基于java的宜佰丰超市进销存管理系统设计与实现.docx
基于java的削面快餐店点餐服务系统的设计与实现.docx
用户体验分享和讨论.ppt
均包含代码,文章,部分项目包含ppt
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REaDme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 、3本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 、本项3目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看ReAdmE.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
均包含代码,文章,部分项目包含ppt
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
志愿者招募网站,在网站首页可以查看首页,组织信息,志愿活动,新闻资讯,个人中心,后台管理等内容,并进行详细操作 用户注册,在用户注册页面通过填写账号,密码,确认密码,姓名,手机,所在学校,邮箱,验证码等信息进行注册操作 组织信息,在组织信息页面可以查看组织名称,组织编号,组织宣言,负责人,联系电话等内容,并进行评论和收藏操作 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssm 前端技术:Vue 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog
全代码在里面,学完Java实训写出来的Java图书馆代码
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。