数据库常见操作三
数据库基本操作会了,下面我们来讲一下查询:连接查询、外连接查询、复合连接条件查询、子查询等。
--连接查询
交叉连接:交叉连接返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。新数据集=A表所有记录 x B表所有记录。
自由连接:自然连接运算的结果表是在参与操作的两个表的共同属性上进行等值条件连接,再去除重复属性后所得的新表。
我们先建几个数据表,以便数据操作:
create table 系部 ( 系部代码 char(6) not null primary key, 系部名称 varchar(30) not null , 系主任 char(8) ) go create table 专业 ( 专业代码 char(4) not null primary key, 专业名称 varchar(20) not null, 系部代码 char(6) constraint wz11 references 系部(系部代码) ) go create table 班级 ( 班级代码 char(9) not null primary key , 班级名称 varchar(20) , 专业代码 char(4) constraint wz1 references 专业(专业代码), 系部代码 char(6) constraint wz2 references 系部(系部代码), 备注 varchar(50) ) go create table 学生 ( 学号 char(12) not null primary key , 姓名 char(8), 性别 char(2), 出生日期 datetime, 入学时间 datetime, 班级代码 char(9) constraint wz3 references 班级(班级代码), 系部代码 char(6) constraint wz4 references 系部(系部代码), 专业代码 char(4) constraint wz5 references 专业(专业代码), 高考分数 int ) go insert 系部(系部代码,系部名称,系主任) values('01','计算机系','老张') go insert 系部(系部代码,系部名称,系主任) values('02','经济管理系','老陈') go insert 系部(系部代码,系部名称,系主任) values('03','机械系','老李') go insert 系部(系部代码,系部名称,系主任) values('04','数学系','老梁') go insert 专业(专业代码,专业名称,系部代码) values('0101','软件工程','01') go insert 专业(专业代码,专业名称,系部代码) values('0102','网络工程','01') go insert 专业(专业代码,专业名称,系部代码) values('0103','信息工程','01') go insert 专业(专业代码,专业名称,系部代码) values('0201','工商管理','02') go insert 专业(专业代码,专业名称,系部代码) values('0202','物流管理','02') go insert 专业(专业代码,专业名称,系部代码) values('0301','模具加工','03') go insert 专业(专业代码,专业名称,系部代码) values('0302','机电一体化','03') go insert 专业(专业代码,专业名称,系部代码) values('0401','应用数学','04') go insert 专业(专业代码,专业名称,系部代码) values('0402','金融数学','04') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010101','软件工程1班','0101','01','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010102','软件工程2班','0101','01','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010103','网络工程1班','0102','01','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010104','网络工程2班','0102','01','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010105','信息工程1班','0103','01','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010106','工商管理1班','0201','02','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010107','物流管理1班','0202','02','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010108','模具加工1班','0301','03','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('010109','应用数学1班','0401','04','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('0101010','金融数学1班','0402','04','暂无') go insert 班级(班级代码,班级名称,专业代码,系部代码,备注) values('0101011','金融数学2班','0402','04','暂无') go insert 学生 values('010101000000','刘德华','男','1988-5-5','2010-9-1','010101','01','0101',356) go insert 学生 values('010101000001','张学友','男','1988-1-4','2010-9-1','010101','01','0101',354) go insert 学生 values('010101000002','梁静茹','女','1988-2-1','2010-9-1','010101','01','0101',342) go insert 学生 values('010101000003','陈奕迅','男','1983-5-3','2010-9-1','010102','01','0101',441) go insert 学生 values('010101000004','张韶涵','女','1987-8-6','2010-9-1','010102','01','0101',354) go insert 学生 values('010101000005','林俊杰','男','1988-6-6','2010-9-1','010102','01','0101',498) go insert 学生 values('010101000006','孙燕姿','女','1984-5-3','2010-9-1','010106','02','0201',522) go insert 学生 values('010101000007','周华健','男','1986-8-6','2010-9-1','010106','02','0201',378) go insert 学生 values('010101000008','尚雯婕','女','1988-6-6','2010-9-1','010106','02','0201',365) go insert 学生 values('010101000009','任贤齐','男','1984-5-3','2010-9-1','010108','03','0301',421) go insert 学生 values('010101000010','魏晨','男','1986-8-6','2010-9-1','010108','03','0301',574) go insert 学生 values('010101000011','庞龙','男','1988-6-6','2010-9-1','010108','03','0301',452) go insert 学生 values('010101000012','刘若英','女','1988-5-3','2010-9-1','0101011','04','0402',354) go insert 学生 values('010101000013','李圣杰','男','1989-8-6','2010-9-1','0101011','04','0402',324) go insert 学生 values('010101000014','克群','男','1989-2-9','2010-9-1','0101011','04','0402',321) go
--交叉连接
select * from 学生 cross join 班级
select 学生.姓名,学生.性别,班级.班级名称 from 学生 cross join 班级
select 学生.姓名,学生.性别,班级.班级名称 from 学生 cross join 班级 where 学生.班级代码=班级.班级代码
--自然连接
select 学生.姓名,学生.性别,班级.班级名称 from 学生 join 班级 on 学生.班级代码=班级.班级代码
--自身连接查询
使用自身连接时,必须为表指定两个别名,以示区别。
select a.姓名,b.性别 from 学生 as a join 学生 as b on a.学号 = b.学号
--外连接查询
外连接的结果集不但包含满足连接条件的行,还包括相应表中的所有行,也就是说,即使某些行不满足连接条件,但仍需要输出该行记录。
外连接包括三种:左外连接、右外连接和完全外连接。
我们建两个简单的表来操作一下:
create table 产品 ( 产品编号 char(9) not null , 产品名称 varchar(20) not null , ) go create table 产品销售 ( 产品编号 char(9) not null , 销量 int ) go insert 产品 values('001','显视器') insert 产品 values('002','键盘') insert 产品 values('003','鼠标') insert 产品销售 values('001','25') insert 产品销售 values('003','35') insert 产品销售 values('005','30')
--左外连接
select * from 产品 left join 产品销售 on 产品.产品编号=产品销售.产品编号
--右外连接
select * from 产品 right join 产品销售 on 产品.产品编号=产品销售.产品编号
--完成外连接
select * from 产品 full join 产品销售 on 产品.产品编号=产品销售.产品编号
--复合连接条件查询
select 学生.学号,学生.姓名,学生.性别,班级.班级名称,专业.专业名称,系部.系部名称 from 学生 join 班级 on 学生.班级代码=班级.班级代码 join 专业 on 学生.专业代码=专业.专业代码 join 系部 on 学生.系部代码=系部.系部代码
--子查询
查询系部代码为01的所以学生
select * from 学生 where 班级代码 in ( select 班级代码 from 班级 where 专业代码 in ( select 专业代码 from 专业 where 系部代码 in ( select 系部代码 from 系部 where 系部代码 in (01) ) ) )
根据学号查询所在系部的所有信息
select * from 系部 where 系部代码 in ( select 系部代码 from 专业 where 专业代码 in ( select 专业代码 from 班级 where 班级代码 in ( select 班级代码 from 学生 where 学号 = '010101000000' ) ) )
查询学生按学号从小到大排序第6到第10共5个学生信息:
select top 5 * from (select top 10 * from 学生 order by 学号 asc) as new_table order by 学号 desc