前段时间用MySQL实现过的,但是由于种种原因得使用sql server,
有关用MySQL实现的方法请参见我的这篇博文:
文章目录
显示所有数据库:
select * from sys.databases; -- 显示所有的数据库
select * from pc;
-- 创建视图
create view pc_view as select * from pc;
select * from pc_view;
显示当前数据库的所有表:
use [computer];
select * from sys.tables; -- 显示所有的表
显示选中表的基本信息:
sp_help pc; --显示pc表的信息
并:
use practice1;
-- 并
select * from
(select * from benke
union all -- 要all的时候不去重,不要的时候会去重
select * from yanjiu) as a;
交:
-- 交
select * from
(select * from benke
intersect
select * from yanjiu) as a;
inner join 实现“交”功能:
-- inner join,实现的功能同“交”,但是有相同的列,需要手动去除
select a.* from (select * from benke)
as
a inner join (select * from yanjiu) as b on a.id = b.id;
差:
-- 差
select * from
(select * from benke
except
select * from yanjiu) as a;
left outer join实现“差”功能:
-- left outer join,实现的功能同“差”,但是有相同的列,需要手动去除
select * from (select * from benke) as a
left outer join
(select * from yanjiu) as b
on a.id = b.id
where b.id is NULL;
delete:
基本格式:
delete语句格式
delete from R where 条件C
use practice1;
select * from benke;
select * from yanjiu;
-- 删除研究生导师关系中,同时也是本科生导师,且性别为男的元组(将把jion删除)
delete from yanjiu where sex = '男' and id in (select id from benke);
insert into yanjiu
values('2004', 'jion', '男');
select * from yanjiu where id in (select id from benke);
benke和yanjiu的关系如图(上为benke 下为yanjiu):
update:
格式:
update table set <更新> where <条件>;
update student set sname='Jack' where sname='marry';
insert:
基本格式:
1.insert into R(属性列表) values (对应属性的值列表)
2.insert into R values(对应关系默认属性的值列表)
3.insert into R(属性列表) select 属性列表 from S
R, S 可以是同一关系
use practice1;
SELECT * FROM student;
-- 插入一个学生信息:
INSERT INTO student(sno, sname, ssex, sage, sdept)
values('06005', 'marry', '女', 20, '经商管理');
INSERT INTO student
values('04001', 'jion','男', '数学', 25);
-- 有一个学号为04005的学生,其他信息和学号为03001的学生一样,插入这个学生的信息:
INSERT INTO student
SELECT '04005', sname, ssex, sdept, sage FROM student WHERE sno='03001';
student关系如下:
left和right函数的用法:
USE [practice1];
SELECT * FROM STUDENT;
-- 经商管理系学生的学号前两位修改为08,其他不变.学号长度为5
UPDATE student
SET sno = '08' + right(sno, LEN(sno) - LEN('08'))
where sdept = '经商管理';
-- 总结left(str, num)和right(str, num)的使用:选取str中从左/右数num个字符
substring函数的用法:
UPDATE student
SET sno = '06' + SUBSTRING(sno, LEN('06') + 1, LEN(sno) - len('06'))
where sdept = '经商管理';
-- 从下面的例子发现,sql中字符串的第一个字符索引为1:
select SUBSTRING(sno, 1, 2) from student where sdept = '经商管理';
-- 总结substring(str, start, num)的用法:从str的第start个字符开始选取num个字符
笛卡尔积:
select * from benke, yanjiu;
select * from benke cross join yanjiu;
等值连接:
-- 等值连接:
select * from benke a join yanjiu b on a.id = b.id;
即需要找连个表的相同字段
多表等值连接:
select 客户.客户编号,客户.姓名,产品编号 from
(订货项目 join 订单 on 订货项目.订单编号=订单.订单编号)
join 客户 on 订单.客户编号=客户.客户编号
全连接:
-- 全连接:
select * from benke a full join yanjiu b on a.id = b.id;
去重:
-- 去重:
select distinct * from yanjiu ;
排序:
-- 排序:
select * from yanjiu order by id;
聚集操作符:
count # 计数
max # 求最大值
min # 求最小值
avg # 求平均值
sum # 求和
分组操作符:
select L, Fun from R
group by
L;
分组操作符常常和聚集操作符连用,这里的fun就是聚集操作符
如果想在分组操作符的前提下加前提条件,不能使用where关键字,
只能使用 having :
select L, Fun from R
group by
L
having L > 200;
嵌套查询:
• 在select … from … where语句结构的where子句中可嵌入一个select语句块
• 其上层查询称为外层查询或父查询,其下层查询称为内层查询或子查询
• SQL语言允许使用多重嵌套查询
• 在子查询中不允许使用order by子句
• 嵌套查询的实现一般是从里到外,即先进行子查询,再把其结果用于父查询作为条件
返回单个值的子查询
如:求与“李芳”同一个系的学生名,年龄(不包含李芳):
- [方法一]:
select Sname, Sage
from student
where Sdept = (select sdept from student where Sname = '李芳')
and ID<>(select ID from student where Sname = '李芳');
- [方法二]:
select FIRST.Sname, FIRST.Sage
from Student FIRST, Student SECOND
where FIRST.Sdept = SECOND.Sdept AND SECOND.Sname = '李芳'
and FIRst.ID <> (select ID from student where Sname = '李芳');
返回一组值的子查询
如:求选修“C6”课程且成绩超过90分的学生
- [方法一]:
select *
from student
where sno IN (select sno from SC where Cno='C6' AND Grade>90);
- [方法二(连接查询)]:
select student.*
from student,SC
where Student.Sno=SC.Sno AND Cno='C6' AND Grade>90;
例:求比计算机系中所有学生年龄小的其他系的学生:
- [方法一]:
select *
from student
where
sdept!='CS' AND
sage < ANY (select Sage from Student where Sdept='CS');
- [方法二]:
select *
from Student
where
Sdept!='CS' AND
Sage < (select MAX(Sage) from Student where Sdept='CS');
多重子查询
表结构:
Teacher(tno, tname, salary, dno)
Department(dno, dname)
例:求工资介于“张三”与“里司”两个之间的职工
select *
from teacher
where
Salary >= (select MIN(Salary) from
teacher where Tname IN ('张三', '里司')) AND
Salary <= (select MAX(Salary) from
teacher where Tname IN ('张三', '里司');
在from语句中使用子查询,对查询结果定义表名及列名
例:求平均成绩超过80分的学号及平均成绩
select Sno, avg_G
from (select Sno, avg(Grade) from
SC group by Sno) AS RA(Sno, avg_G)
where avg_G > 80;
带有exists的相关子查询
• 不相关子查询:子查询的查询条件不依赖于父查询的称为不相关子查询。
• 相关子查询:子查询的查询条件依赖于外层父查询的某个属性值的称为相关子查询,带exists 的子查询就是相关子查询
• exists表示存在量词,带有exists的子查询不返回任何记录的数据,只返回逻辑值“True” 或“False”
例:求所有选修了“C1”课程的学生名。
不相关子查询
select Sname from student
where sno IN ( select sno from SC where Cno = 'C1' );
相关子查询
select Sname from student
where exists
(select * from SC where student.sno=SC.sno AND Cno = 'C1' );
相关子查询执行过程:先在外层查询中取student表的第一个元组(记录),用该记录的相关的属性值(在内层where子句中给定的)处理内层查询,若外层的where子句返回‘TRUE’值,则此元组送入结果的表中。然后再取下一个元组;重复上述过程直到外层表的记录全部遍历一次为止。
• 不关心子查询的具体内容,因此用 select * exists + 子查询用来判断该子查询是否返回元组
• 当子查询的结果集非空时,exists 为“True”;当子查询的结果集为空时,exists为“False”。
• not exists :若子查询结果为空,返回“TRUE”值,否则返回“FALSE”
索引
创建索引
常用的索引:唯一索引和聚簇索引
唯一索引:
对于已含重复值的属性列不能建UNIQUE索引
对某个列建立UNIQUE索引后,插入新记录时DBMS会自动检查新记录在该列上是否取了重复值。这相当于增加了一个UNIQUE约束
create unique index Stusno on Student(Sno ASC);
聚簇索引
建立聚簇索引后,基表中数据也需要按指定的聚簇属性值的升序或降序存放。也即聚簇索引的索引项顺序与表中记录的物理顺序一致.
create cluster index stu_sname on Student(Sname);
在Student表的Sname列上建立一个聚簇索引,而且Student表中的记录将按照Sname值的升序存放。Sql server中的表示方式create clustered index。某些DMBS不支持聚簇索引,所以用前一定要查使用说明。
在一个基本表上最多只能建立一个聚簇索引
聚簇索引的用途:对于某些类型的查询,可以提高查询效率
聚簇索引的适用范围:很少对基表进行增删操作;很少对其中的变长列进行修改操作
删除索引
删除索引时,系统会从数据字典中删去有关该索引的描述。
DROP INDEX [表名.]<索引名>;
如:
DROP INDEX Student.stu_sname;
视图
创建视图:
创建一个学生年龄不大于19岁的计算机科学与技术专业的学生信息视图:
create view 学生年龄视图
as
select 学号, 姓名, 出生日期 from 学生信息
where datediff(year, 出生日期, getdate())<=19
and 学号 in
(select 学号 from 学生信息 where 专业='计算机科学与技术');
DATEDIFF(datepart,startdate,enddate):
返回两个指定日期的日期和时间边界数(差值),datepart 规定了用日期的哪一部分(year、month、day、week、hour等)来计算差额。
GETDATE():
获得当前时间
删除视图:
可以同时多个一起删除:
drop view 订单信息视图, 产品信息视图, 客户订购产品视图;