|
|

楼主 |
发表于 2013/8/22 11:47:56
|
显示全部楼层
本帖最后由 YUGENPING 于 2013/8/22 16:29 编辑
白天继续学习PLSQL了,晚上继续搭建环境了,学的比较零散了
开发中碰到的小问题
1 需要让平均值保留几位小数点输出:select ... cast(AVG(列名) as numeric(m,n)) from ... 其中m是几位有效数字,n表示的是小数点后几位
2 加深SQL语句的执行顺序:
SQL Select语句完整的执行顺序:
1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、使用order by对结果集进行排序。
3 左/右连接
有时需要将进行连接的其中一个表作为基准显示全部的数据,根据连接条件在其它表中可能会出现无法匹配的数据,此时就用空值来代替。比如显示员工信息时,有的员工可能还没有分配到某个具体的部门(新进员工),其所属部门一项就没有数据,但是员工仍然需要显示,即员工表数据需要全部显示。
具体语法:select ... from table1 t1 left join table2 t2 on ti.id = t2.id; --左连接
或 select ... from table1 t1 right join table2 t2 on ti.id = t2.id; --右连接
左还是右的区别,简单地说左(右)连接就是指join的左(右)边是基准表,全部数据都要显示,根据
连接条件无法进行连接的记录就用空值代替。比如: select e.empno, e.ename, d.dname from emp e left join dept d on e.deptno =d.deptno;
还没有分配到某个具体的部门的员工的e.deptno肯定是没有值的,无法满足“e.deptno = d.deptno”的条件,但由于是左连接,左边的员工表的数据必然会显示,这时该员工的部门名称就是空值。若是right join ... on,就表示部门表的数据全部显示,员工表中无法连接的数据就是空值代替,意思就是说这个部门还没有员工,因为在员工表中没有一条记录的deptno与该部门的deptno相匹配(可能是刚刚成立的新部门)
在Oracle中,对于左/右连接和全连接还有一种特殊的表示方法,使用“(+)”符号,
例如:select ... from table1 t1, table2 t2 where ti.id = t2.id(+); --左连接
select ... from table1 t1, table2 t2 where ti.id(+) = t2.id; --右连接
与SQL SERVER相比,Oracle没有Top n 这样简单方便取前几名的方法.
但也有相对应的方法可以实现,使用的是Oracle中的伪列:rownum.
最简单的方法如下:
一:最简单的问题:直接取前几名
SELECT A.* from Company_Expense A WHERE ROWNUM<=N
(注意,在上句中我们没有指定按哪列进行排序,而具体rownum序号是依据哪一列,现在我都不确定。但可以明确一点的是,如果我们按主键进行排序,rownum号不会乱,但如果指定其它列的号,序号有可能会乱)
二:麻烦一点的:取后几名
上面方法的一点变通,首先在内部以某列进行排列,在外面取
select V.* from
(
select rownum,A.* from company_expense A
order by a.expenseid desc
)V where rownum<3
三:变态一点的:取前几名,但值相同的记录为同一名次
比如:对班级学生成绩进行排名,第一名:100,共2名,第二名,98,共5名........如此类推,取出排名前十名的所有学生。
基本思路是:先使用Distinct取得成绩的前十名,并使用rownum排序.这样可以得出第十名的值,然后取所有成绩大于等于第十名的所有学生信息。
记录得到后,然后再与刚使用Distinct取得成绩为前十名,且有rownum序号的表Join,以成绩为条件。就可以得到正常的排名次序。
相关代码请参考如下脚本:
select rownum, T.Row_Num, v.*
from (select A.Name,
A.Employee_Code,
v.STATUS,
To_Char(v.JOIN_DATE, 'yyyy-mm-dd') Join_Date,
V.Unit_Name,
p.line_description Line_Num,
sum(a.last_result) Sum_result
from QM_QUALITY_LEVEL_JUDGE A,
hr_lbr_employee_tl_tbl_v v,
Qm_Product_Line P
Where a.employee_code = v.EMPLOYEE_CODE
And A.LINE_NUM = P.Line_Num
And To_Char(A.Index_Date, 'yyyy-mm-dd') >= '2006-05-01'
And To_Char(A.Index_Date, 'yyyy-mm-dd') <= '2006-07-24'
And A.Last_Result > 0
group by A.Name,
A.Employee_Code,
V.STATUS,
V.JOIN_DATE,
V.Unit_Name,
A.Line_Num,
P.LINE_DESCRIPTION
order by Sum_Result desc, employee_code desc) v ---基本的信息
left join (select rownum row_Num, v.*
from (select distinct sum(a.last_result) Sum_result
from QM_QUALITY_LEVEL_JUDGE A,
hr_lbr_employee_tl_tbl_v v,
Qm_Product_Line P
Where a.employee_code = v.EMPLOYEE_CODE
And A.LINE_NUM = P.Line_Num
And To_Char(A.Index_Date, 'yyyy-mm-dd') >=
'2006-05-01'
And To_Char(A.Index_Date, 'yyyy-mm-dd') <=
'2006-07-24'
And A.Last_Result > 0
group by A.Name,
A.Employee_Code,
V.STATUS,
V.JOIN_DATE,
V.Unit_Name,
A.Line_Num,
P.LINE_DESCRIPTION
Order by Sum_Result Desc) v
Where rownum <= 10) T On v.Sum_Result = T.Sum_Result --得到正确的排名序号
-----以下条件是取得所有大于第十名成绩的记录
where V.sum_Result >=
(select min(Sum_Result) Sum_Result
from (select rownum row_Num, v.*
from (select distinct sum(a.last_result) Sum_result
from QM_QUALITY_LEVEL_JUDGE A,
hr_lbr_employee_tl_tbl_v v,
Qm_Product_Line P
Where a.employee_code = v.EMPLOYEE_CODE
And A.LINE_NUM = P.Line_Num
And To_Char(A.Index_Date, 'yyyy-mm-dd') >=
'2006-05-01'
And To_Char(A.Index_Date, 'yyyy-mm-dd') <=
'2006-07-24'
And A.Last_Result > 0
group by A.Name,
A.Employee_Code,
V.STATUS,
V.JOIN_DATE,
V.Unit_Name,
A.Line_Num,
P.LINE_DESCRIPTION
Order By Sum_Result Desc) v
Where rownum <= 10))
|
|