SQLServer 学习笔记2

1.union、union all、except、intersect之间的区别

(1)union:取两个表的并集,如果有重复数据,则只留下一个

(2)union all:在并集的基础上,保留重复的数据

(3)except: 例如select * from A except select * from B,取差集,也就是去掉A和B之间的重复数据,只保留A表独有的部分

(4)intersect 只保留两张表之间相同的数据,也就是取交集

 2.自连接

select * from Customers t1,Customers t2 where t1.City <> t2.City;

3.全连接

全连接类似于union,也就是两个表的并集,查询后的总条数:A表条数+B表条数-两者重复条数

4.左连接、右连接

注意一对多、多对一的关系,例如A表有ID为1的一条数据,而B表有3条ID为1的数据,两表左、右连接,结果为

ID NAME ID NAME
1 A 1 a
1 A 1 b
1 A 1 c

出现这一结果的原因为:1条父数据对应着3条子数据,父数据的信息会自动填充在每条子数据对应的父数据字段。

PS:需要注意的是,连接查询on之后的条件可以不是A表字段=B表字段,可以是其他条件。

另外SqlServer表别名可用不用AS 直接在后面填写即可,例如

select A.*,B.C#,B.score from (select * from SC where C# = '01')A --查询结果做A表
inner join (select * from SC where C# = '02')B--查询结果做B表
on A.S# = B.S# --两表连接查询
where A.score>B.score; 

5.null的问题

例如:select * from Person where pname <> '张三';,如果pname这个字段内有null,则null对应的这行数据会被自动忽略,也就是说逻辑判断的值是不包含null的。

另外,在update 数据时,如果要填入null,直接填写字段=null即可,但是在判断时,要使用 where 字段 is null | is not null。

6.更新、删除数据时需要注意:

先使用select查询到要操作的信息,然后再用update、delete进行具体操作,防止误操作。

7.隐式转换问题

例如一个字段是int类型,在插入数据时插入'1',数据可以被正确存入,不报错,这是SQL自动将字符串类型转换为了整数类型,但是如果输入的是'a1',则会产生报错,因为'a1'是无法被转换为int类型的!

 8.查找每门课最高分问题

先得到相同学科的最高分数,再查询Scores表,找到最高分数的记录:

select * from Scores a where a.sco_degree = 
(select max(b.sco_degree) from Scores b where a.sco_cour_id = b.sco_cour_id);

找到每门课的最高分数

select max(sco_degree) from Scores where sco_cour_id = a.sco_cour_id --先筛选出每门学科 即sco_cour_id = a.sco_cour_id,然后求最大值,得出的就是每门课的最高分

然后用本表去筛选这些最高分对应的信息:

select * from Scores a where sco_degree = 

 第二种方式:

(1)先按照课程id把成绩表分组,然后求出最高分

select max(sco_degree) score,sco_cour_id from Scores group by sco_cour_id;

(2)然后把上面的结果集做a表,然后成绩表做b表,查询两者成绩、课程编号一样的数据

select b.* from (select max(sco_degree)score,sco_cour_id from Scores group by sco_cour_id)a,Scores b where a.score = b.sco_degree and a.sco_cour_id = b.sco_cour_id;

9.数据类型

date与datetime的区别:

date时间格式为:yyyy-mm-dd

datetime时间格式为: yyyy-mm-dd hh:mi:ss.ms,精确到毫秒时间,时间格式与getdate()函数格式一样,因此可以用来计算毫秒时间差,用于性能统计

declare @d datetime
set @d = getdate()
数据操作语句,例如查询语句等
select ['语句执行耗时'] = datediff(ms,@d,getdate());

 10.获取当月天数与当月最后一天、第一天

--当月第一天
--当前日期+(-当期日期天数+1) 
--例如 现在时间7月19号 19+(-19+1) = 1
select dateadd(d,-day(getdate())+1,getdate());
--当月最后一天
--下月的这一天减去现在日数 
--例如现在时间7月19 下月 这一天8月19 8/19-19 = 8/0即 7/31
--即使这个月有31号而下月只有30天也没事,只要产生月份/0日这个结果就可以
select dateadd(d,-day(getdate()),dateadd(m,1,getdate()));
--本月有多少天
select day(dateadd(d,-day(getdate()),dateadd(m,1,getdate())));

 11,in 与 group by

学生表:

 成绩表:

现在要查询和‘1’号学生所学科目完全相同的学生信息

首先要筛选学号,所学科目 in ‘1’号学生所学科目

select S# from SC where C# in (select C# from SC where S# = '01');

查询出的结果:

select C# from SC where S# = '01'; --查询出的结果是‘01’,‘02’,‘03’

只要在课程编号在'01','02','03'都被查询出来,拿08号学生来说,学习了02,03,04三门课,所以只匹配中了两门,S#查询出两个08

然后我们依据S#进行编组查询:

select S# from SC where C# in (select C# from SC where S# = '01') group by S#;

数据根据S#编组,重复出现的数据被合并,此时我们只需要知道每个S#对应的课程编号数量等于01学生所学的课程数量:

select S# from SC where C# in (select C# from SC where S# = '01') group by S# 
having count(c#)=(select count(c#) from sc where S# = '01');

接下来只需查询Student表中对应这几个S#的学生信息即可:

select * from Student where S# in
(select S# from SC where C# in (select C# from SC where S# = '01' )group by S# 
having count(c#)=(select count(c#) from sc where S# = '01'));

 12.数据类型隐式转换

select count(*)*1.00 from SC group by sid;

count()得到是一个整数,*1.00后隐式转为浮点数

 13.delete update 高级应用

利用join 会实现条件删除与更新数据

例:

根据课程表内语文课程考试成绩小于60分的学生学号去匹配学生表,匹配中的学生表记录删除

delete A from Student A left join Score B on A.sid = B.sid where course = '语文' and degree <60;

 类似的,update也可以这样使用

 update A set age = 100 from Student A left join Score B on  .... where ....;

posted @ 2018-07-12 16:32  0==1&1==0  阅读(2476)  评论(0编辑  收藏  举报