查询语句

练习链接

查询语句_第1张图片
students表
查询语句_第2张图片
classes表


1 查询所有数据

查询students表的所有数据


SELECT * FROM students;


SELECT可以用作计算,直接计算出表达式的结果,但它并不是SQL的强项。

但是不带FROM子句的SELECT语句,可用来判断当前到数据库的连接是否有效。

许多检测工具会执行一条SELECT 1,来测试数据库连接。


2 条件查询

1)查询分数在80分以上的学生记录。


SELECT * FROM students WHERE score >= 80;


2)符合条件“分数在80分或以上”,并且还符合条件“男生”


SELECT * FROM students WHERE score >= 80 AND gender = 'M';



3)符合条件“分数在80分或以上”或者“男生”


SELECT * FROM students WHERE score >= 80 OR gender = 'M';



4)符合条件“不是2班的学生”,NOT查询不是很常用


SELECT * FROM students WHERE NOT class_id = 2;



5)分数在80以下或者90以上,并且是男生


SELECT * FROM students WHERE (score < 80 OR score > 90) AND gender = 'M';



NOT优先级最高,其次是AND,最后是OR。加上括号可以改变优先级。

3 投影查询

1)只希望返回某些列的数据,而不是所有列的数;

例如,从students表中返回id、score和name这三列:


SELECT id, score, name FROM students;


2)还可以给每一列起个别名,这样,结果集的列名就可以与原表的列名不同。

例如,以下SELECT语句将列名score重命名为points,而id和name列名保持不变:


SELECT id, score points, name FROM students;



4 排序

查询结果集通常是按照id排序的,也就是根据主键排序。

1)加上ORDER BY子句,改为其他条件排序,例如按照成绩从低到高进行排序:


SELECT id, name, gender, score FROM students ORDER BY score;


2)如要反过来,按照成绩从高到底排序,末尾加上DESC表示“倒序”:


SELECT id, name, gender, score FROM students ORDER BY score DESC;


3)如果score列有相同数据进一步排序,可以继续添加列名。

例如,使用ORDER BY score DESC, gender表示先按score列倒序,如果有相同分数的,再按gender列排序:


SELECT id, name, gender, score FROM students ORDER BY score DESC, gender;


4)有WHERE子句,ORDER BY要放到WHERE后。

例如,查询一班的学生成绩,并按照倒序排序:


SELECT id, name, gender, score

FROM students

WHERE class_id = 1

ORDER BY score DESC;



5 分页查询

SELECT查询时,如几万行数据,一个页面显示数据量太大,不如分页显示,每次显示100条。

步骤如下:

1)我们先把所有学生按照成绩从高到低进行排序:


SELECT id, name, gender, score FROM students ORDER BY score DESC;


2)把结果集分页,每页3条记录。

查询第1页记录,可以使用LIMIT 3 OFFSET 0:


SELECT id, name, gender, score

FROM students

ORDER BY score DESC

LIMIT 3 OFFSET 0;



如果要查询第2页,需要“跳过”头3条记录。(每页记录条数* (页码 - 1))

也就是对结果集从3号记录开始查询,把OFFSET设定为3:


SELECT id, name, gender, score

FROM students

ORDER BY score DESC

LIMIT 3 OFFSET 3;



如果原本记录集一共就10条记录,但我们把OFFSET设置为20,显示结果如下:


Empty result set


OFFSET超过了查询的最大数量并不会报错,而是得到一个空的结果集。


6 聚合查询

统计一张表的数据量,例如,想查询students表一共有多少条记录:


SELECT COUNT(*) FROM students;


通常,使用聚合查询时,我们应该给列名设置一个别名,便于处理结果:


SELECT COUNT(*) num FROM students;


除了COUNT()函数外,SQL还提供了如下聚合函数:

查询语句_第3张图片

分组聚合

SQL还提供了“分组聚合”的功能,按class_id分组:


SELECT COUNT(*) num FROM students GROUP BY class_id;



可以把class_id列也放入结果集中,便于查看班级:


SELECT class_id, COUNT(*) num FROM students GROUP BY class_id;



聚合查询的列中,只能放入分组的列。

并没有按照name分类,以下报错:


SELECT name, class_id, COUNT(*) num FROM students GROUP BY class_id;



也可以使用多个列进行分组。

例如,我们想统计各班的男生和女生人数:


SELECT class_id, gender, COUNT(*) num FROM students GROUP BY class_id, gender;


查询语句_第4张图片
上述结果


7 多表查询

1) SELECT可以从多张表同时查询数据。

例如,同时从students表和classes表的“乘积”,又称笛卡尔查询:


SELECT * FROM students, classes;


查询语句_第5张图片
……未截完……

以上为students表的每一行,与classes表的每一行,两两拼在一起返回。

结果集列数 = students列数 + classes列数

结果集行数 = students行数 * classes行数


2) 上述结果集有两列id和两列name,不好区分。

要解决这个问题,可以利用投影查询的“设置列的别名”来给两个表各自的id和name列起别名:


SELECT

    students.id sid,

    students.name,

    students.gender,

    students.score,

    classes.id cid,

    classes.name cname

FROM students, classes;


SQL还允许给表设置一个别名,让我们在投影查询中引用起来稍微简洁一点:


SELECT

    s.id sid,

    s.name,

    s.gender,

    s.score,

    c.id cid,

    c.name cname

FROM students s, classes c;


多表查询也是可以添加WHERE条件的,我们来试试:


SELECT    

    s.id sid,

    s.name,

    s.gender,

    s.score,

    c.id cid,

    c.name cname

FROM students s, classes c

WHERE s.gender = 'M' AND c.id = 1;


8 连接查询

连接查询对多个表进行JOIN运算。

先确定一个主表作为结果集,然后把其他表的行,有选择性地“连接”在主表结果集上。

例如,我们想要选出students表的所有学生信息,可以用一条简单的SELECT语句完成:


SELECT s.id, s.name, s.class_id, s.gender, s.score FROM students s;


查询语句_第6张图片

上面的结果集只有class_id列,缺少对应班级的name列。

存放班级名称的name列存储在classes表中,

需要根据students表的class_id,找到classes表对应的行的name列,就可得班级名称。

此时可通过 内连接——INNER JOIN来实现:


SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score

FROM students s

INNER JOIN classes c

ON s.class_id = c.id;


查询语句_第7张图片

有内连接(INNER JOIN)就有外连接(OUTER JOIN)。

我们把内连接查询改成外连接查询:


SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score

FROM students s

RIGHT OUTER JOIN classes c

ON s.class_id = c.id;


效果如下:

查询语句_第8张图片

多出来的一行“四班”,但是,学生相关的列如name、gender、score都为NULL。

这也容易理解,因为根据ON条件s.class_id = c.id,classes表的id=4的行正是“四班”,但是,students表中并不存在class_id=4的行。



此外有 LEFT OUTER JOIN,以及 FULL OUTER JOIN。它们的区别是:

1. INNER JOIN只返回同时存在于两张表的行数据。

由于students表的class_id包含1,2,3,classes表的id包含1,2,3,4,所以,INNER JOIN根据条件s.class_id = c.id返回的结果集仅包含1,2,3。

2. RIGHT OUTER JOIN返回右表都存在的行。

如果某一行仅在右表存在,那么结果集就会以NULL填充剩下的字段。

3. LEFT OUTER JOIN则返回左表都存在的行。

如果我们给students表增加一列,并添加class_id=5,由于classes表并不存在id=5的列,所以,LEFT OUTER JOIN的结果会增加一列,对应的class_name是NULL.

4. FULL OUTER JOIN,它会把两张表的所有记录全部选择出来。

并且,自动把对方不存在的列填充为NULL。


查询语句_第9张图片
查询语句_第10张图片

你可能感兴趣的:(查询语句)