搜索
您的当前位置:首页正文

SQL深入学习

来源:小奈知识网
spool D:/a.txt //a.txt为文件名 指定sqlplus下产生的数据导出的文件。

spool off

把在sqlplus下产生的数据导出。

column 字段名 format [a[ n]] |[nnnn ] 设置字段,也就是列的显示宽度(让显示好看点)。 如column ename format a10 //10个字符的宽度 column sal format 99999 //5位数的宽度

有个问题,假设两张表都有ename字段,那么应该是设置谁的宽度呢?有待实验

set pagesize n 设置每页显示记录n条。

如 set pagesize 17 每页显示17条(包括空行和字段名字行)。

show pagesize

显示每页显示记录多少,也就是上面说的n

ed

打开最近一条sql语句缓存。

/

执行缓存的sql语句

内连接有两种方式

1、显性连接 from .. inner join ... on.. 如:select * from

emp e inner join dept d on e.deptno=d.deptno; 2、隐性连接 from ... where 列的关联条件 如:select * from emp e,dept d where e.deptno=d.deptno;

外连接有两种方式,以下例子都是以emp e1表为驱动表,驱动表的意思就是驱动表的会全部显示。

1、显性连接 from .. left join ... on..

如:select e1.empno,e1.ename,e1.mgr,e2.ename MGRNAME from emp e1 left join emp e2 on e1.mgr = e2.empno;

2、隐性连接 where 列连接条件(+)=列连接条件或列连接条件=列连接条件(+) 表示.

如:select e1.empno,e1.ename,e1.mgr,e2.ename MGRNAME from emp e1,emp e2 where e1.mgr = e2.empno(+)

having语句

W3school的解释是,在SQL中增加Having子句的原因,where语句关键字无法与合计函数一起使用。

如:select e.deptno,sum(e.sal) from emp e group by e.deptno having sum(e.sal)>9000

exsit

表表达式也可以成为where 判断和对比的条件信息.数据库为我们提供exists和in()这些方法,它们可以以被查询出来的表表达式为参照条件进行判断,选择那些符合条件的行,来生成新的中间结果表. Where 不光可以一对一的判断,也可以一对多的判断. 一对多就是以一个复合行的数据结构(表表达式)为判断条件, 一对一就是以一个标量表达式为判断标准.

--查出在纽约的部门的员工的年薪(薪水*12)的两种方法 内连接 (一对一)

select e.empno,e.ename,e.sal*12 ANNUAL_SALLY from emp e,dept d where e.deptno = d.deptno --内连接 隐性 and d.loc = 'NEW YORK';

EXISTS (一对多)

select e.empno,e.ename,e.sal*12 ANNUAL_SALLY from emp e where exists(

select * from dept d

where d.deptno = e.deptno and d.loc = 'NEW YORK' )

如果我们使用一对一的判断方法需要把emp表和dept表建立一个内连接,在内连接生成的中间结果表中一对一的判断选择符合条件的行信息.把符合条件的行生成一个新的中间结果表传给客户端.

如果我们使用以表表达式来进行一对多的判断方法,只需将emp表的中间结果表的每行的deptno的列信息(看判断条件选择列信息),把deptno列信息拿到dept表中去判断,如果符合条件则将该行信息,保存到新的中间结果表中。 最后显示新的中间结果表。

这两种方法在不同条件下各有各的优点,只能通过开发者的经验来判断在什么情况下使用该方法。

SQL语句记录:

--每个部门大于部门平均工资的人员名字,工资金额。 select e.ename,e.sal from emp e where exists(

select * from emp e1

where e1.deptno = e.deptno group by e1.empno

having avg(e1.sal) > e.sal )

行转列介绍

在很多时候会有一些行转列方面的业务需求。例如

(工资表) 名称 张淋淋 张淋淋 张淋淋 张淋淋 张淋淋 李静 李静 李静 李静 月份 1 2 3 4 5 1 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140

我们需要通过SQL查询出一个这样的结果表业务。

名称 张淋淋 李静 1 1200 1110 2 1210 1120 3 1220 1130 4 1230 1140 5 1240

步骤一 通过FROM 产生一个中间结果表。

名称 张淋淋 张淋淋 张淋淋 张淋淋 张淋淋 李静 李静 李静 李静 月份 1 2 3 4 5 1 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140 步骤二 GROUP BY 以名称为分组条件。得到一个新的中间结果表

名称 月份 1 2 张淋淋 3 4 5 1 李静 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140

步骤三 我们通过SELECT 关键字在新的中间结果表中增加5个新列,每个列上的数据都是通过判断函数decode,判断指定条件得到的数据。判断月份,如果复合行中的月份与判断条件相同,数据库会将与这个月份所对应的工资金额拿出来.将它放到新列,新列有可能出现复合行所有我们也需要一个sum聚合函数来把这个列合并成一个标量表达式

中间表创建过程。

名称 月份 1 2 张淋淋 3 4 5 1 李静 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140 Decode(月份,1,工资金额)如果月份列等于1,就把于1月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 Decode(月份,2,工资金额)如果月份列等于2,就把于2月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 1 Decode(月份,1,工资金额)如果月份列等于1,就把于1月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 2 Decode(月份,2,工资金额)如果月份列等于2,就把于2月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 …..

步骤三 中间结果表

名称 张淋淋 李静 1 1200 1110 2 1210 1120 3 1220 1130 4 1230 1140 5 1240

步骤四 将中间结果表信息,发送给客户端。 SQL 文

我们需要注意的是,要想在中间结果表中增加或者减少列,只能通过select 关键字来做。也就是说只有在SELECT 这个步骤的时候我们才有机会在中间结果表中有增减列的行为。在现在的SQL标准中还不能做到把GROUP BY 分组产生的复合行列直接在SELECT关键字步骤中遍历为列。只能通过我们自己手写SELECT 关键字部分来达到对中间结构表增减列。所以在行转列的时候,就需要我们事先知道行中的信息,再通过SELECT 关键字把行中的信息拿到列中使用判断函数取出符合条件的复合行,最后再聚合函数将它们生成新的列。注意不管抽取的列信息是不是复合行,都需要用聚合函数合并成标量表达式.

行转列介绍

在很多时候会有一些行转列方面的业务需求。例如

(工资表) 名称 张淋淋 张淋淋 张淋淋 张淋淋 张淋淋 李静 李静 李静 李静 月份 1 2 3 4 5 1 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140

我们需要通过SQL查询出一个这样的结果表业务。

名称 张淋淋 李静 1 1200 1110 2 1210 1120 3 1220 1130 4 1230 1140 5 1240

步骤一 通过FROM 产生一个中间结果表。

名称 张淋淋 张淋淋 张淋淋 张淋淋 张淋淋 李静 李静 李静 李静 月份 1 2 3 4 5 1 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140 步骤二 GROUP BY 以名称为分组条件。得到一个新的中间结果表

名称 月份 1 2 张淋淋 3 4 5 1 李静 2 3 4 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140

步骤三 我们通过SELECT 关键字在新的中间结果表中增加5个新列,每个列上的数据都是通过判断函数decode,判断指定条件得到的数据。判断月份,如果复合行中的月份与判断条件相同,数据库会将与这个月份所对应的工资金额拿出来.将它放到新列,新列有可能出现复合行所有我们也需要一个sum聚合函数来把这个列合并成一个标量表达式

中间表创建过程。

名称 月份 1 2 工资金额 1200 1210 1220 1230 1240 1110 1120 1130 1140 1 Decode(月份,1,工资金额)如果月份列等于1,就把于1月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 2 Decode(月份,2,工资金额)如果月份列等于2,就把于2月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 ….. 张淋淋 3 4 5 1 2 3 4 Decode(月份,1,工资金额)如果月份列等于1,就把于1月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 Decode(月份,2,工资金额)如果月份列等于2,就把于2月份对应的工资金额信息拿到新列中 在sum聚合成一个标量 李静

步骤三 中间结果表

名称 张淋淋 李静 1 1200 1110 2 1210 1120 3 1220 1130 4 1230 1140 5 1240

步骤四 将中间结果表信息,发送给客户端。 SQL 文

我们需要注意的是,要想在中间结果表中增加或者减少列,只能通过select 关键字来做。也就是说只有在SELECT 这个步骤的时候我们才有机会在中间结果表中有增减列的行为。在现在的SQL标准中还不能做到把GROUP BY 分组产生的复合行列直接在SELECT关键字步骤中遍历为列。只能通过我们自己手写SELECT 关键字部分来达到对中间结构表增减列。所以在行转列的时候,就需要我们事先知道行中的信息,再通过SELECT 关键字把行中的信息拿到列中使用判断函数取出符合条件的复合行,最后再聚合函数将它们生成新的列。注意不管抽取的列信息是不是复合行,都需要用聚合函数合并成标量表达式.

--给出每个部门工资前

2名的SQL

select * --步骤三 from emp e --步骤一 where 2>( --步骤二

select count(*) from( --步骤二点三 select e2.deptno,e2.sal

from emp e2 --步骤二点一点一

group by e2.deptno,e2.sal --步骤二点一点二

) e1 --步骤二点一 where e1.deptno = e.deptno --步骤二点二 and e1.sal>e.sal )

order by e.deptno --步骤四

步骤一:先根据select的关键字和emp e生成一个中间表M1 步骤二:把中间表M1的每行数据放入进去比较。

步骤二点一:根据select关键字和中间表M2生成中间表M3

步骤二点一点一:先根据select的关键字和emp e2生成一个中间表M2

步骤二点一点二:在M2,根据分组group by关键字做列名,相同数据进行分组合并。(这里的group by有两个关键字,必须要两个关键字的列的数据全部相同才能合并)

步骤二点二:在M3,把M1的行数据拿进where语句,把符合条件生成一个中间表M4。

步骤二点三:在M4中,聚合函数把行表达式装换为标量表达式 步骤三:聚合函数把行表达式装换为标量表达式(这里没有聚合函数) 步骤四:根据order by 排序。

例 给出员工所在部门是人力又是财会的同时存在2个部门的人员名单.

(人员部门职务表) 名称 张淋淋 张淋淋 张淋淋 张淋淋 李静 李静 李文 李文 张萍 张萍 方芳 方芳 部门 人力 人力 财会 后勤 人力 后勤 财会 财会 人力 财会 人力 人力 职务 科员 前台 科员 科员 科员 科长 出纳 会计 科长 科长 科员 副科长

步骤一 FROM关键字将人员部门职务表中的信息放入一个中间结果表中

步骤一 产生的中间结果表

名称 张淋淋 张淋淋 张淋淋 张淋淋 部门 人力 人力 财会 后勤 职务 科员 前台 科员 科员 李静 李静 李文 李文 张萍 张萍 方芳 方芳 人力 后勤 财会 财会 人力 财会 人力 人力 科员 科长 出纳 会计 科长 科长 科员 副科长

步骤二 GROUP BY 将人员名称为分组条件,生成一个新的中间结果表.

步骤二 产生的中间结果表中

名称 部门 人力 张淋淋 人力 财会 后勤 李静 李文 张萍 方芳 人力 后勤 财会 财会 人力 财会 人力 人力 职务 科员 前台 科员 科员 科员 科长 出纳 会计 科长 科长 科员 副科长

步骤三 使用 HAVING 关键字来判断那些行符合条件. Decode(部门,人力,1)判断每行的部门列(复合行)中是否有人力存在,如果存在返回1.即使行中出现多个人力部门信息Decode函数也将返回1,在使用同样的方法判断财会部门.在将2个函数的结果相加.通过判断它们的总和是否大于1,大于1就将这行数据放入中间结果表中. having (sum(decode(部门,'人力',1))+sum(decode(部门,'财会',1)))>1

步骤三 产生的中间结果表中

名称 部门 人力 张淋淋 人力 财会 后勤 张萍 人力 财会 职务 科员 前台 科员 科员 科长 科长

步骤四 SELECT 选择名称列,生成中间结果表

步骤四 产生的中间结果表中

名称 张淋淋 张萍 SQL文

因篇幅问题不能全部显示,请点此查看更多更全内容

Top