外连接

来源:互联网 发布:域名腾讯云管家认证 编辑:程序博客网 时间:2024/04/28 06:19
定义:不但返回满足连接条件的所有记录,而且会返回部门不满足连接条件的记录
分类:
左外连接:不但返回满足连接条件的所有记录,而且会返回左表不满足连接条件的记录
右外

左外连接连接运行原理:

select * from emp "E"left join dept "D"on E.deptno=D.deptno

1. 用左表的第一行分别和右表的所有行进行连接,如果有匹配的行,则一起输出,如果右表有多行匹配,则结果集输出多行,如有没有匹配行,则结果集中只输出一行,该输出行左边为左表第一行内容,右表全部输出null,
2. 然后再用左表第二行和右边所有行进行连接,如有匹配的行,则一起输出,如果右表有多行匹配,则结果集输出多行,如果没有匹配行,则结果集中只输出一行,该输出行左边为左表第二行的内容,右边全部输出null,
3. 以此类推,直至左边所有行连接完毕
4. 因为右边很可能出现有多行和左边某一行匹配,所以左连接产生的结果集的行数很可能大于left join左边表的记录的总数
5. 帮助文档:左向外联接的结果集包括left outer子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表均为空值。

左外连接的实际意义:
返回一个事物及其该事物的相关信息,如果该事物没有相关信息,则输出null
例子:
已知条件:
productstocks 货物库存表  orderform订单表  pID产品编号
SQL语句:SELECT productstocks.*, orderform.*
from productstocks
left join orderform
on productstocks.pID=orderform.pID
实际意义:
返回仓库中现存货物的信息及其该货物的订单信息,如果该货物没有订单信息则把该货物输出为null

完全连接
SELECT productstocks.*, orderform.*
from productstocks
full join orderform
on productstocks.pID=orderform.pID

交叉连接
select * from emp cross join dept
等价于
select* from emp,dept

自连接
定义: 一张表中自己和自己连接起来查询数据
例子: 不用聚合函数求薪水最高的员工信息

select * from empwhere empno not in(select distinct "E1".empno from emp "E1"join emp "E2"on "E1".sal<"E2".sal)

使用聚合函数:
select * from emp
where sal= (select max(sal) from emp)

联合
定义:
表和表之间的数据以纵向的方式连接在一起
注意:以前的连接都是以横向的方式连接在一起
例子: 输出每个员工的姓名 工资 上司姓名

select "E1".ename "姓名","E1".sal "工资","E2".ename "上司"from emp "E1"join emp "E2"on "E1".mgr="E2".empnounionselect ename ,sal ,'本人'from empwhere mgr is null

注意:
若干个select语句联合在一起满足的条件
1.这若干select语句输出列数相同
2.这若干个select语句输出列的数据类型必须是兼容的

分页查询
--第一页
select top 3 *  
from emp 
order by sal desc
--第二页
select top 3 * from emp
where empno not in (select top 3 empno from emp order by sal desc)
order by sal desc
--第三页
select top 3 * from emp
where empno not in (select top 6 empno from emp order by sal desc)
order by sal desc
假设每页显示n条记录,当前要显示的是第m页,表名是A 主键是A_id
select top n *
from A
where A_id not in (select top (m-1)*n A_id from A)
identity(主键自动增长,用户不需要为identity修饰的主键赋值)
create table student
( stu_id int primary key identity(100,2),  
  stu_name nchar(200) 
)
insert into student(stu_name) values ('张三');
insert into student values ('张三');--ok
insert into student values ('李四');
delete from student where stu_name='李四'
insert into student values ('李四');--删除在出入会导致主键的不连续
视图
为什么需要视图
示例:求出平均工资最高的部门的编号和部门的平均工资
select * from
(select deptno, avg(sal) "avg_sal"
from emp
group by deptno
) "T"
where "T"."avg_sal"=
(select max("E".avg_sal)
from (select deptno, avg(sal) "avg_sal"
from emp
group by deptno
) "E"
)
--采用视图
create view v$_emp_1
as
(select deptno, avg(sal) "avg_sal"
from emp
group by deptno)
select * from v$_emp_1
where "v$_emp_1"."avg_sal"=
(select max("v$_emp_1"."avg_sal")
from v$_emp_1
)
总结:简化查询
避免代码冗余
什么是视图
视图是个select语句
视图逻辑上被当做一个虚拟的表看待
视图的格式
create view 视图的名字
as
--select前面不能加begin
select 语句
--select后面不能加end
视图的优点
简化查询
增加数据的保密性
视图缺点
增加数据库维护的成本
如emp表中数据删了要对视图里面的数据更新
视图只能简化查询,并不能加快查询
注意问题:
创建视图的select语句必须为所有的计算列指定别名
--error
create view v$_a
as 
select avg(sal) from emp
--ok
create view v$_a
as 
select avg(sal) as "avg_sal" from emp
视图不是物理表,是虚拟表
不建议通过视图更新视图所依附的原始表的或结果
事务(重要)
为什么需要事务?
事务是用来保证数据的合理性和并发处理的能力
或者说:
事务可以保证避免数据处于一种不合理的中间状态
利用事务可以实现多个永辉对共享资源的同时访问
例子:
银行中的转账操作,账户A把一定数量的款项转到账户B上,这个操作包括两个步骤,一个是从账户A上把存款减去一定数量,二是在账户B上把存款加上相同的数量。这两个步骤显然要么都完成,要么都取消,否则银行就会受损失。显然,这个转账操作中的两个步骤就构成一个事务
假设A和B用户都希望查询修改M表数据,A用户不应该刚把M表的数据改成5,查询时显示的数据却是8(因为B用户修改M表的数据成8了),事务必须得保证多个用户对共享资源同时访问时,数据给用户的反应是合理的。
1.避免数据处于不合理的中间状态
转账
2.怎样避免多用户同时访问时呈现给永辉的数据是合理的
该问题很复杂,现在仍然没有很好的解决方法
事务和线程的关系
事务也是通过锁来解决很多问题的
线程同步就是通过锁来解决的
事务和第三方插件的关系
直接使用事务库技术难度很大,很多人是借助第三方插件来实现
因此我们一般人不需要细细研究数据库中事务的语法细节
第三方插件要想完成预期的功能,一般必须得借助数据库中的事务机制
什么是事务
一系列操作要么全部执行成功要么全部执行失败这就是事务。
如何创建事务
T-SQL使用下列语句来管理事务
        开始事务:begin transaction
        提交事务:commit transaction
        回滚(撤销)事务:rollback transaction
一旦事务提交或回滚,则事务结束
判断某条语句执行是否出错:
使用全局变量@@error
@@error只能判断当前一条T-SQL语句执行是否有错,为了判断事务中所有T-SQL语句是否有错,我们需要对错误进行累计:如 set @errorsum=@errorsum+@@error
事务三种运行模式:
自动提交事务
每条单独的语句都是一个事务。如果成功执行,则自动提交;如果错误,则自动回滚
这是sqlserver2005默认的模式
显示事务
每个事务均以begin transaction语句显示开始,
以commit或rollback语句显示结束
隐性事务
在前一个事务完成时新事务隐式启动,但每个事务仍以commit或rollback语句
总结事务的四大特性:
事务的这四大属性简称ACID属性
原子性:事务是一个完整的操作。事务的各步操作时不可分的(原子的);要么都执行,要么都不执行。
一致性:当食物完成时,数据必须处于一致状态,要么处于开始状态要么处于结束状态不允许出现中间状态!
隔离性:指当前的事务与其他未完成的事务是隔离的。在不同的隔离级别下,事务的读取操作,可以得到的结果是不同的。
持久性:事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。
注意问题:
不能在sql server 2000中单独使用commit;rollback;语句
delete from dept2 where deptno =50
commit --error
rollback --error
因为一条语句默认的就是一个事物写完就提交但oracle中可以
事务举例:
create table bank
(
customerEname nvarchar(200),
currentMoney money
    )
alter table bank add constraint check_currentMoney check (currentMoney>=1)


insert into bank values('张三',1000)
insert into bank values('李四',1)


select * from bank


begin transaction 
declare @errorSum int
set @errorSum=0
update bank set currentMoney=currentMoney-1000
where customerEname='张三'
set @errorSum=@errorSum+@@error
update bank set currentMoney=currentMoney+1000
where customerEname='李四'
set @errorSum=@errorSum+@@error
if (@errorSum <> 0)
begin
print '转账失败'
rollback transaction
end
else
begin 
print '转账成功'
commit transaction
end

SQL2005后面内容还有
嵌套查询

索引
存储过程
游标
TL-SQL
触发器