数据库系统讲人话系列 SQL 之 Select 大法

本文将讲述select语句的详细用法,select用于对数据查询,我们对一个数据库的操作大部分时候都是对数据进行查询,我们将通过使用select语句来满足各种各样的查询需求。实验环境我们使用SQLiteStudio:
在这里插入图片描述
为了研究方便,我们将使用以下预备数据环境:(一共三张表)

  • Student(Sno, Sname, Ssex, Sage, Sdept) 学生信息表
  • Course(Cno, Cname, Cpno, Ccredit) 课程表
  • SC(Sno, Cno, Grade) 学生选课表

Cpno是先修课程名称,也就是我们在修这门课之前需要先修某门课的名称。

1. 单表查询

假如现在我们只在一个数据表里面查询。

1.1 选中表中的某若干列

例:查询全体学生的学号和姓名

select Sno,Sname from Student

关系代数式子:
∏ S n a o , S n a m e ( S t u d e n t ) \prod_{Snao,Sname}(Student) Snao,Sname(Student)

假如我们需要获取整个表的记录:

select * from Student
1.2 系统函数的使用

例:我们需要获取全体学生的姓名和出生年份

select Sname, 2020-Sage from Student;

但这样是不好的,因为把常数写入了代码里面,我们在代码里面需要规避常数的出现。
这时候我们需要到系统函数来计算当前的年份

select sname ,year(getdate())-sage as birthday from student;

附:as 是显示的列别名,只对查询结果和过程有效,对原表不产生影响。
在这里插入图片描述
假如我们要小写字母标识的话,需要到系统函数:lower(<col_name>)

select lower(sdept) from student;
1.3 选择表中的若干行(元组)

选择行一个最大问题就是重复项的出现,我们需要到 关键字 “distinct” 来消除
假如我们需要到查询选修了课程的学生的学号
假如我们使用

select sno from sc

会有重复的,因为一个学生会选择多门课

我们只需要使用:

select distinct sno from sc

即可对【结果】行出现重复的元组进行去重。
注意是对结果进行去重,对原表没有影响。
distinct 是对整个元组的重复起作用的,不是对某个属性的去重。

1.4 条件查询【大小】

我们更多情况是进行条件查询,这时候需要到 where 关键字了。
条件查询包括:【大小】,【范围】,【集合】,【字符串匹配】,【空值查询】,【多重条件】的知识

最简单就是大小,运算符如下:
= , > , < , < = , > = , ! = , < > , ! > , ! < =,>,<,<=,>=,!=,<>,!>,!< =,>,<,<=,>=,!=,<>,!>,!<
<>是不等于的意思和!=是一样的

查询计算机系全体学生的名单:

select Sname from student where Sdept='CS'

查询所有成绩不及格的学生学号:

select distinct sno from sc where grade<60
1.5 条件查询【范围】

虽然我们使用大小也能确定范围,但是关于范围我们由更专业的一套表达:between and 和 not betweeen and。

查询年龄在20-23岁的学生的姓名,性别,年龄:

select sname, ssex, sage from student where sage between 20 and 23
1.6 条件查询【集合】

在等值查询(某个属性等于某个数值)的时候,我们只能给出一个等值条件,假如我们有多个呢?我们就需要到集合 in(v1,v2…) 函数来表达。

例如我们需要查询在信息系(IS),数学系(MA),计算机科学系(CS)的学生的姓名和性别。

select sname,ssex from student where sdept in('IS','MA','CS');

那假如我们需要查询不是某些值的话:not in 即可

select sname,ssex from student where sdept not in('IS','MA','CS');
1.7 条件查询【字符串匹配】

我们需要到正则表达式来进行匹配,需要到关键字 like
在sql里面使用到的正则表达语法我们只需要掌握两个:%和_,%标识不定长字符串,_标识单个字符。

假如我们需要查找所有姓“刘”的学生的姓名,学号和性别:

select sname,sno,ssex from student where sname like "刘%";

假如否定:

select sname sno,ssex from student where sname not like "刘%";

假如我们需要使用到%和_作为正常的字符:
使用escape关键字

select Cno from Course where like 'DB\_Design' escape '\'
1.8 条件查询【空值查询】

在一个数据表中我不可避免会存在空值,这个时候就需要我们使用 is null 和 is not null 来查询了,注意的是空值不能使用=那些符号计算。
例如我们需要查询某些学生缺少成绩的对应的课程号

select sno,cno from sc where grade is null;
1.9 条件查询【多重条件】

对于多重条件,我们使用 and 和 or 来满足

1.10 查询结果的排序

我们将使用order by 关键字

  • 降序:order by <col_name> desc
  • 升序:order by <col_name>

对全体学生的年龄进行排序降序:

select sno from student order by ssage desc

对系号进行升序排序, 对年龄降序排序:

select * from student order by sdept,sage desc
1.11 集函数的使用:统计,求最值
  • 统计个数 count(<col_name>)
  • 求和 sum(<col_name>)
  • 求平均 avg(<col_name>)
  • 求最值 min/max (<colo_name>)

需要注意的是count函数不统计空值。

统计学生的总人数:

select count(*) from student 

在这里插入图片描述
统计1号课程的平均成绩:

select avg(grade) from sc where cno=1
1.12 对查询结果进行分组

这个用于细化集函数的作用对象,因为我们直接使用集函数是对所有的查询结果进行操作的,那现在假如我们对不同的查询分组,那就需要到 group by 关键字了。

求每个课程号的选择的人数:

select cno,count(sno) from sc group by cno

查询每个课程90分以上的人数:

select cno,count(sno) where grade>90 group by cno;

这个先把所有的大于90分的人找出来,再进行分组,sql是按照语法的顺序执行操作的。

1.3 对查询结果进行二次操作集函数

也就是我们对查询结果不满足,还需要对查询之后的结果再进行一次查询,需要到having关键字。

例如查询选修了3门课程以上的学生学号

select sno from sc group by sno having count(*)>=3

我们首先把选课记录以学号为相同元素归并起来,再对每个组筛选出总数大于3的sno

select sno from sc group by sno

执行之后:

sno
01
01
02
02
02
03

然后我们对每个group 进行having 操作 集函数

例如:
统计每门课的最高分:

select cno,grade from sc group by cno having max(grade)

执行逻辑
先根据cno分组把相同的cno的元组筛选出来,然后对于每一个组的grade进行统计最高分

表数据:
在这里插入图片描述
执行结果:
在这里插入图片描述

2. 多表查询

以上我们只是涉及了单表查询,也就是我们只是在一个表里面寻找答案,但是往往答案会在多个表出现,我们需要把结果整合起来。

不同的表的列名字,我们需要使用表的前缀进行定义:
Student.sno 和 SC.sno 是不同的

把查询结果连接在一起,这个时候就涉及到连接查询了

2.1 等值连接

假如我们执行:

select Student.*,SC.* from student,SC

得到:
在这里插入图片描述
这样子是没有意义的,因为里面出现了重复的列,而且元组的数据没有一致的意义。这个只是最普通的笛卡尔积。我们需要真正有意义的是:等值连接

实例:查询每个学生的所有信息和他所选修课程的情况

select  Student.*,SC.* from Student,SC where Student.sno=SC.sno

在这里插入图片描述
我们需要使用=来划出一个桥,说白了就是构建两个表之间的关系。

实例:查询计算机系(CS)的学生的学号,姓名,所在系,选修的课程号,成绩

select Student.sno,Student.sname,Student.sdpet,SC.cno,SC.grade from Student,SC where Student.sno=SC.sno and Sdept='CS' 
2.2 自身连接

假如某些时候我们需要到一个表的两次使用(比如使用同一个表连接起来),我们需要对表进行起别名再连接。

这种情况出现在一个表的某个列的信息依赖于该表其他列信息的情况。

比如:查询每门课程的先修课程的课程号

select a1.cno,a2.cno from Course a1, Course a2 where a1.cpno=a2.cno

在这里插入图片描述
实例:查询同时选修2号课程和3号课程的学生的学号

select a.sno from SC a, SC b where a.sno=b.sno and a.cno!=b.cno and a.cno=2 and b.cno=3

在这里插入图片描述

2.3 复合条件的多表查询
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值