实际工作中,绝大部分查询并非一个表可以解决,我们需要合并,连接表格。所有查询都其实都是在简单查询的基础上进行的。
一、表格的合并(纵向增加)
表格的合并或者说加法,是把两个表格加在一起,这个操作增加的是行,也就是说表格会边长。
假设有个两个表如下
表 :course
表: course1
经过这个union 操作后,两个表合在一起,可以看到是长度增加了,union操作默认是自动去重的,这个类似Python 里的set 的union操作。如果要保留的话,union 后面要加上关键字 all。
这里要强调一下,通常数据库里并不希望有重复数据,数据分析的清洗阶段,如果没有特殊要求,也是要去重的,重复的数据会影响数据的正确性和统一性。所以没有一般的要求,union不用增加 all 关键字。
(二)表格的连接(横向增加)
每个表格都代表一定的关系,如果要把这些关系关联起来,就需要做表格的连接操作(join),join和union 不同,union后的表格列是不变的,增加的是记录。join操作,row 不会增加,还可能因为条件而减少,但是新的表格代表了另外一个关系,表格会变宽,新增加的列代表了原有关系基础上增加或者新发现的关系。在数据库中,表的关联比表格的增加用的更多,能够表达和实现的功能也更多。
连接方式:
交叉连接,左连接,右连接,内连接。
交叉连接即笛卡尔积,又叫全连接,A表的每一列都和B 表的每一列连接。形成的表格长度是A的行数*B的行数。表格大的时候,谨慎使用,表格会变得非常大,冗余数据会非常多。全连接不需要where条件
内连接: 连接两个表格的共有部分相关的记录。
左连接:A 左连接B,新表中是所有A的记录和B表中与A表有共同数据的记录
右连接:A 右连接B,新表中是所有B的记录和A表中与B表有共同数据的记录
表的连接使用join,join 后面用ON 连接,表明两个表通过哪些列产生匹配关系,而不是where。 JOIN 语句需要使用别名方便操作。
举例如下:
外连接:
全连接
从上图可以看到,全连接表格会很大,而且实际生活中没有太大的意义,所以用的并不多。
下面针对以下两个表做一下左连接和右连接操作
score
course1
左连接
右连接
可以从学号这列数据的顺序看出来SQL操作实际是不同的
内连接
从结果可以看出来,1 左连接和右连接会分别保留左边或者右边的表格,有空值项也不会影响操作,被连接进来的表格根据连接条件,满足的被加进来。2 内连接是左侧和右侧同时只保留符合条件的记录,不符合条件的记录就不再加进来了。
左连接和右连接的作用是,可以对集合做减法或者指定要保留某个表的全部数据,,这个在实际中会用到,其他时候都是内连接。
现在可以根据以上做一个查询,成绩表和学生表中找到学生的总成绩和选课数目
成绩表和学生表分别如下
计算过程和结果如下
或者查询平均成绩大于85分的学生
查询学号,姓名,课程号,课程名称
因为表结构的关系,需要三个表才能找到所有数据,学生选课信息在成绩表里,课程名称在课程表里。用where或者join 都可以,需要注意,where 语句是把连接的两个表写在一起,而join不行,要join一个,写好条件后 ,再join 另外一个。具体操作如图所示
(三) case语句
分类计算表达式,基本结构
case when 判断 then 表达式
when 判断 then 表达式
。。。。。
when 判断 then 表达式
else
end
case中满足条件后,后面的语句就不执行了。需要注意的是,else可以不写,但是不建议这么做。End 不能省,表示语句结束。Case表达式可以写在任意语句中。下面这个例子中,case 语句分别对成绩做判断,然后生成一个新的列,然后同时对这个新生成的列做了求和操作,可见case 语句可是生成新的列,并且可以放在sql 的很多地方。此外,因为select 中只能是group by里的名称,加上需要显示课程名称,所以group by需要加上课程名称,groupby 后面加的列要求对结果没影响,否则不能加上,这个比较好理解,分组的数据不能影响SQL的结果。
举例如下: 学生成绩分段统计,