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

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

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

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

MySQL 两个sql 取 并集 sql取两张表的并集_c#

MySQL 两个sql 取 并集 sql取两张表的并集_字段_02

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

2.自连接



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



3.全连接

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

MySQL 两个sql 取 并集 sql取两张表的并集_字段_03

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

学生表:

MySQL 两个sql 取 并集 sql取两张表的并集_字段_04

 成绩表:

MySQL 两个sql 取 并集 sql取两张表的并集_MySQL 两个sql 取 并集_05

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

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



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



查询出的结果:

MySQL 两个sql 取 并集 sql取两张表的并集_MySQL 两个sql 取 并集_06



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#;



MySQL 两个sql 取 并集 sql取两张表的并集_字段_07

数据根据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');



MySQL 两个sql 取 并集 sql取两张表的并集_MySQL 两个sql 取 并集_08

接下来只需查询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'));



MySQL 两个sql 取 并集 sql取两张表的并集_MySQL 两个sql 取 并集_09

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 ....;