SELECT * from student,class
在上一篇博客里我们已经介绍了Sql语句的增删改,以及创建了用来演示增删改的数据库和表,下面我们介绍SQL语句中最重要的查询语句。
增删改博客链接(Sql语句之增删改查(CRUD)-CSDN博客)
select name from student

select name,sex from student
select * from student
SELECT是关键字,表示将要执行一个查询,*表示“所有列”,FROM表示将要从哪个表查询
注意:查询结果也是一个二维表,它包含列名和每一行的数据
| 运算符 | 说明 |
| = | 等于 |
| <>或!= | 不等于 |
| 小于 | |
| 小于等于 | |
| > | 大于 |
| >= | 大于等于 |
| between..and... | 两个值之间 |
| is null | 为null |
| and | 并且 |
| or | 或者 |
| in | 包含 |
| not | not可以取非,主要用在is或in |
| like | like为模糊查询,支持%或_匹配 |
SELECT * FROM student where class_num = '20201001';
SELECT name FROM student where age = 20
需要查询多个字段的时候,字段之间以“,”(逗号)隔开
SELECT name,sex FROM student where class_num = '20201001';
SELECT name FROM student where age <> 20 SELECT name FROM student where age != 20
SELECT * FROM student where age < 21
SELECT * FROM student where age between 21 and 25
SELECT * FROM student where class_num is null
SELECT * FROM student where class_num = '20201001' and sex = '男'
SELECT * FROM student where class_num in ('20201001','20201002')
IN 操作符允许我们在 WHERE 子句中规定多个值。
select * from student where id in (1,3)
通配符:
%表示任意多个字符
_表示单个字符)
SELECT * FROM student WHERE name like '王%';
SELECT * FROM student WHERE name like '王_';
SELECT * FR OM student WHERE name like '%张%';
| sum | 求和 |
| avg | 取平均 |
| max | 取最大值 |
| min | 取最小值 |
| count | 取得记录数 |
好吧,这个应该没什么实际作用,不过懒得在建新表演示了
select sum(age) from student;
select avg(age) from student;
SELECT max(age) from student
SELECT count(*) from student;
SELECT count(class_num) from student
注意:
1、count(*)表示取得当前查询表所有记录
2、count(字段名称),不会统计为null的记录
SELECT avg(age),class_num from student GROUP BY class_num

SELECT count(age),class_num,age from student GROUP BY class_num,age

SELECT max(age),class_num from student GROUP BY class_num
我们使用SELECT查询时,细心的读者可能注意到,查询结果集通常是按照id排序的,也就是根据主键排序。这也是大部分数据库的做法。如果我们要根据其他条件排序怎么办?可以加上ORDER BY子句。
SELECT * FROM student ORDER BY age;
如果要反过来,按照年龄降序,我们可以加上DESC
SELECT * FROM student ORDER BY age DESC;
SELECT * FROM student ORDER BY age DESC,sno;
默认的排序规则是ASC:“升序”,即ORDER BY ageASC和ORDER BY age是相同的。
SELECT * FROM student ORDER BY class_num,age;
记录会先按照class_num升序排列,若class_num相同则会按照age升序排列,所以字段名越靠左排序优先级越高
使用SELECT查询时,如果结果集数据量很大,比如几万行数据,可是每次前端只能呈现最多20条数据,这样不仅全部查询出来浪费时间,而且还需要进行选取20条的操作,费时费力,我们不妨一次先查询20条,等到前端再次发出请求,比如点击下一页,再查询新的数据,返回给前端,这就是分页查询的sql实现。
要实现分页功能,实际上就是从结果集中显示第1~20条记录作为第1页,显示第21~40条记录作为第2页,以此类推。因此,分页实际上就是从结果集中“截取”出第M~N条记录。这个查询可以通过LIMIT OFFSET 子句实现。我们先把所有学生按照班级从高到低进行排序:
现在,我们把结果集分页,每页3条记录。要获取第1页的记录,可以使用LIMIT 3 OFFSET 0:
SELECT * FROM student LIMIT 3 OFFSET 0;

上述查询LIMIT 3 OFFSET 0表示,对结果集从0号记录开始,最多取3条。
注意SQL记录集的索引从0开始。
如果要查询第2页,那么我们只需要“跳过”头3条记录,也就是对结果集从3号记录开始查询,把OFFSET设定为3:
SELECT * FROM student LIMIT 3 OFFSET 3;
上面的查询均是单表查询,不过我们在开发的时候,肯定不会是所有字段全部在一张表上,而是很多张表,比如教师信息和学生信息几乎没可能出现在一张表上,所以联表查询是肯定会出现的情况。
含义:若两张表进行联表查询的时候没有任何条件限制,最终的查询结果总数是两张表记录的成绩,该现象称为笛卡尔积现象。
就像这样
SELECT s.name,c.class_name from student s,class c

如果想要得到每个学生和其所在的班级名就应该加上限制语句
WHERE s.class_num = c.class_num
- SELECT s.name,c.class_name
- from student s,class c
- WHERE s.class_num = c.class_num
上面的写法属于sql92
缺点:表连接条件与查询条件放在一起,没有分离
select xxx from A 表名 join B 表名 on 表的连接条件;
- select student.name,class.class_name
- from student
- join class
- on student.class_num = class.class_num;
优点:表连接独立,结构清晰,如果结果数据不满足要求,可再追加where条件进行过滤;
- SELECT
- student.name,class.class_name
- from
- student
- INNER JOIN
- class
- on
- student.class_num = class.class_num;
包含左边表的全部行(不管右边的表中是否存在与他们匹配的行),以及右边表中全部匹配的行。
- SELECT
- student.name,class.class_name
- from student
- LEFT JOIN class on
- student.class_num = class.class_num;
包含右边表的全部行(不管右边的表中是否存在与他们匹配的行),以及左边表中全部匹配的行。
- SELECT
- student.name,class.class_name
- from student
- RIGHT JOIN class
- on student.class_num = class.class_num;
select xxx from A表 join B表 on 连接条件1 join C表 on 连接条件2
查询出每个学生所选择的课程
- SELECT
- student.name,course.gradeName
- from student
- join relationship
- on student.sno = relationship.sno
- join course
- on relationship.cno = course.cno
一般在子查询中,程序先运行在嵌套在最内层的语句,再运行外层。因此在写子查询语句时,可以先测试下内层的子查询语句是否输出了想要的内容,再一层层往外测试,增加子查询正确率,因为多层的嵌套使语句可读性很低。
- select
- t1.name
- FROM
- (SELECT student.name,relationship.cno
- FROM student
- INNER JOIN relationship
- on student.sno = relationship.sno) t1
- WHERE
- t1.cno = '1001';
内层查询就是()中的部分,t1是内层查询出的二维表的别名
- SELECT t2.name
- FROM
- (select t1.name,scoure.gradeName
- from
- (SELECT student.name,relationship.cno
- FROM
- student INNER JOIN relationship
- on student.sno = relationship.sno) t1
- INNER JOIN scoure
- on t1.cno = scoure.cno) t2
- where gradeName = '数学';
提示:不是所有的同学都有班级
- SELECT student.name,class.class_name
- from student
- INNER JOIN class
- on student.class_num = class.class_num;
提示:可以使用limit
select * FROM student ORDER BY age DESC LIMIT 1 OFFSET 0;
- SELECT
- age,count(age) c_age
- FROM
- student GROUP BY age
- ORDER BY c_age desc
- LIMIT 1 OFFSET 0
- SELECT t3.name FROM
- (select t2.sno,student.name,student.age FROM student right JOIN
- (select t1.sno FROM
- (select relationship.sno,relationship.cno,course.gradeName
- FROM relationship
- INNER JOIN course on relationship.cno = course.cno) t1
- WHERE t1.gradeName = 'Jvm基础') t2
- on student.sno = t2.sno) t3
- where age > 21;
- SELECT
- t3.name,
- course.gradeName
- FROM
- (
- SELECT
- t2.name,
- relationship.cno
- FROM
- (
- SELECT
- t1.sno,
- t1.name,
- t1.age
- FROM
- (
- SELECT
- student.sno,
- student.name,
- student.age,
- class.class_name
- FROM
- student
- INNER JOIN class ON student.class_num = class.class_num
- ) t1
- WHERE
- t1.class_name = '彩虹班'
- ORDER BY
- age DESC
- LIMIT 1 OFFSET 0
- ) t2
- INNER JOIN relationship ON t2.sno = relationship.sno
- ) t3
- INNER JOIN course ON t3.cno = course.cno;
