SQL查询语句汇总

SQL查询语句汇总

students

id class_id name gender score
1 1 小明 M 90
2 1 小红 F 95

class

id name
1 一班
2 二班
3 三班
4 四班

1.基本查询

-- 查询students表的所有数据

复制代码
SELECT * FROM students;

使用SELECT * FROM students时,SELECT是关键字,表示将要执行一个查询,*表示"所有列",FROM表示将要从哪个表查询

2.条件查询

例如,要指定条件"分数在80分或以上的学生",写成WHERE条件就是SELECT * FROM students WHERE score >= 80。

其中,WHERE关键字后面的score >= 80就是条件。score是列名,该列存储了学生的成绩,因此,score >= 80就筛选出了指定条件的记录:

复制代码
SELECT * FROM students WHERE score >= 80;
SELECT * FROM students WHERE score >= 80 AND gender = 'M';
SELECT * FROM students WHERE score >= 80 OR gender = 'M';
SELECT * FROM students WHERE NOT class_id = 2;
SELECT * FROM students WHERE (score < 80 OR score > 90) AND gender = 'M';
3.投影查询

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

复制代码
 SELECT id, score, name FROM students; 

使用SELECT 列1, 列2, 列3 FROM ...时,还可以给每一列起个别名,这样,结果集的列名就可以与原表的列名不同。它的语法是SELECT 列1 别名1, 列2 别名2, 列3 别名3 FROM ...
例如,以下SELECT语句将列名score重命名为points,而id和name列名保持不变:

复制代码
SELECT id, score points, name FROM students;
SELECT id, score points, name FROM students WHERE gender = 'M';

4.排序

例如按照成绩从低到高进行排序:

复制代码
SELECT id, name, gender, score FROM students ORDER BY score;

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

如果score列有相同的数据,要进一步排序,可以继续添加列名。例如,使用ORDER BY score DESC, gender表示先按score列倒序,如果有相同分数的,再按gender列排序:

复制代码
SELECT id, name, gender, score FROM students ORDER BY score DESC, gender;

默认的排序规则是ASC:"升序",即从小到大。ASC可以省略,即ORDER BY score ASC和ORDER BY score效果一样。

如果有WHERE子句,那么ORDER BY子句要放到WHERE子句后面。例如,查询一班的学生成绩,并按照倒序排序:

复制代码
SELECT id, name, gender, score 
FROM students 
WHERE class_id = 1
ORDER BY score DESC;

5.分页查询

分页实际上就是从结果集中"截取"出第M~N条记录。这个查询可以通过LIMIT <N-M> OFFSET <M>子句实现。我们先把所有学生按照成绩从高到低进行排序:

我们把结果集分页,每页3条记录。要获取第1页的记录,可以使用LIMIT 3 OFFSET 0:对结果集从0号记录开始,最多取3条。注意SQL记录集的索引从0开始

复制代码
SELECT id, name, gender, score
FROM students
ORDER BY score DESC
LIMIT 3 OFFSET 0;

如果要查询第2页,那么我们只需要"跳过"头3条记录,也就是对结果集从3号记录开始查询,把OFFSET设定为3:

复制代码
SELECT id, name, gender, score
FROM students
ORDER BY score DESC
LIMIT 3 OFFSET 3;

LIMIT 3表示的意思是"最多3条记录"。

  • LIMIT总是设定为pageSize;

  • OFFSET计算公式为pageSize * (pageIndex - 1)。

注意:OFFSET是可选的,如果只写LIMIT 15,那么相当于LIMIT 15 OFFSET 0。

在MySQL中,LIMIT 15 OFFSET 30还可以简写成LIMIT 30, 15。

使用LIMIT <M> OFFSET <N>分页时,随着N越来越大,查询效率也会越来越低。

SQL Server中可采用以下sql语句:

复制代码
 --查前五条信息
 select TOP 5 *from students; 
复制代码
--如果要查 第四条到第七条信息
SELECT TOP 4 * FROM students
WHERE students.id
NOT IN
(SELECT TOP 3 id FROM students)

Oracle中可采用以下sql语句:

复制代码
1 --查前五条信息
2 SELECT * FROM EMP  WHERE ROWNUM <= 5;
复制代码
1 --如果要查 第四条到第七条信息
2 select * from (select t.*,rownum rn from tmmis01 t)
3 where rn>=4 and rn<=7

6.聚合查询

查询students表一共有多少条记录为例,我们可以使用SQL内置的COUNT()函数查询

复制代码
 1 SELECT COUNT(*) FROM students; 

-- 使用聚合查询并设置结果集的列名为num:

复制代码
 1 SELECT COUNT(*) num FROM students; 

COUNT(*)和COUNT(id)实际上是一样的效果。另外注意,聚合查询同样可以使用WHERE条件,因此我们可以方便地统计出有多少男生、多少女生、多少80分以上的学生等:

复制代码
 SELECT COUNT(*) boys FROM students WHERE gender = 'M'; 

|-----|---------------------|
| SUM | 计算某一列的合计值,该列必须为数值类型 |
| AVG | 计算某一列的平均值,该列必须为数值类型 |
| MAX | 计算某一列的最大值 |
| MIN | 计算某一列的最小值 |

注意,MAX()和MIN()函数并不限于数值类型。如果是字符类型,MAX()和MIN()会返回排序最后和排序最前的字符。

复制代码
1 -- 使用聚合查询计算男生平均成绩:
2 SELECT AVG(score) average FROM students WHERE gender = 'M';

如果聚合查询的WHERE条件没有匹配到任何行,COUNT()会返回0,而SUM()、AVG()、MAX()和MIN()会返回NULL。

分组

如果我们要统计一班的学生数量,我们知道,可以用 SELECT COUNT(*) num FROM students WHERE class_id = 1; 如果要继续统计二班、三班的学生数量,难道必须不断修改WHERE条件来执行SELECT语句吗?
对于聚合查询,SQL还提供了"分组聚合"的功能。我们观察下面的聚合查询:

复制代码
 SELECT class_id, COUNT(*) num FROM students GROUP BY class_id; 

结果为三个结果:

class_id num
1 4
2 3
3 3

需注意分组后,只能 select 分组的字段,如果查询其他字段会提示"不是 GROUP BY 表达式"

复制代码
1 --通过class_id, gender分组查询
2 SELECT class_id, gender, COUNT(*) num FROM students
3 GROUP BY class_id, gender;
复制代码
class_id gender num
1 M 2
1 F 2
2 F ### 17

7.多表查询

例如,同时从students表和classes表的"乘积",即查询数据,可以这么写:

复制代码
1 SELECT * FROM students, classes;
复制代码
1 SELECT
2     students.id sid,
3     students.name,
4     students.gender,
5     students.score,
6     classes.id cid,
7     classes.name cname
8 FROM students, classes;
复制代码
1 SELECT
2     s.id sid,
3     s.name,
4     s.gender,
5     s.score,
6     c.id cid,
7     c.name cname
8 FROM students s, classes c
9 WHERE s.gender = 'M' AND c.id = 1;

8.连接查询

复制代码
 SELECT s.id, s.name, s.class_id, s.gender, s.score FROM students s; 

现在问题来了,存放班级名称的name列存储在classes表中,只有根据students表的class_id,找到classes表对应的行,再取出name列,就可以获得班级名称。连接查询就派上了用场。我们先使用最常用的一种内连接------INNER JOIN来实现:

复制代码
1 SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
2 FROM students s
3 INNER JOIN classes c
4 ON s.class_id = c.id;
复制代码
 
复制代码
1 SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
2 FROM students s
3 LEFT OUTER JOIN classes c
4 ON s.class_id = c.id;
复制代码
1 SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
2 FROM students s
3 RIGHT OUTER JOIN classes c
4 ON s.class_id = c.id;
复制代码
1 SELECT s.id, s.name, s.class_id, c.name class_name, s.gender, s.score
2 FROM students s
3 FULL OUTER JOIN classes c
4 ON s.class_id = c.id;

注意INNER JOIN查询的写法是:

  1. 先确定主表,仍然使用FROM <表1>的语法;
  2. 再确定需要连接的表,使用INNER JOIN <表2>的语法;
  3. 然后确定连接条件,使用ON <条件...>,这里的条件是s.class_id = c.id,表示students表的class_id列与classes表的id列相同的行需要连接;
  4. 可选:加上WHERE子句、ORDER BY等子句。
    使用别名不是必须的,但可以更好地简化查询语句。
    那什么是内连接(INNER JOIN)呢?先别着急,有内连接(INNER JOIN)就有外连接(OUTER JOIN)。我们把内连接查询改成外连接查询,看看效果:

执行上述RIGHT OUTER JOIN可以看到,和INNER JOIN相比,RIGHT OUTER JOIN多了一行,多出来的一行是"四班",但是,学生相关的列如name、gender、score都为NULL。

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

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

INNER JOIN只返回同时存在于两张表的行数据,由于students表的class_id包含1,2,3,classes表的id包含1,2,3,4,所以,INNER JOIN根据条件s.class_id = c.id返回的结果集仅包含1,2,3。

**RIGHT OUTER JOIN返回右表都存在的行。**如果某一行仅在右表存在,那么结果集就会以NULL填充剩下的字段。

**LEFT OUTER JOIN则返回左表都存在的行。**如果我们给students表增加一行,并添加class_id=5,由于classes表并不存在id=5的行,所以,LEFT OUTER JOIN的结果会增加一行,对应的class_name是NULL。

最后,我们使用FULL OUTER JOIN,它会把两张表的所有记录全部选择出来,并且,自动把对方不存在的列填充为NULL


相关推荐
NineData4 个月前
NineData全面支持PostgreSQL可视化表结构设计
数据库·postgresql·可视化·devops·sql语句·ninedata·表结构设计
苏生Susheng4 个月前
【Oracle】Oracle常用语句大全
java·数据库·sql·mysql·oracle·sql语句·数据库语法
华为云开发者联盟5 个月前
浅析MySQL 8.0直方图原理
sql语句·华为云开发者联盟·查询优化
Sarapines Programmer5 个月前
【测试SQLite】测试SQLite支持的SQL语句分类
分类·sqlite·测试·sql语句·功能
杰克逊的日记7 个月前
数据库连接查询
数据库·mysql·oracle·sql语句·db2·ibm·联合查询
华为云开发者联盟7 个月前
解密数仓的SQL ON ANYWHERE技术
sql语句·华为云开发者联盟·华为云gaussdb(dws)
华为云开发者联盟9 个月前
GaussDB(for MySQL)剪枝功能,让查询性能提升70倍!
sql语句·华为云开发者联盟·华为云数据库
肉肉肉肉肉肉~丸子1 年前
MySQL~SQL语句
数据库·sql·mysql·oracle·sql语句·mysql基础知识