跳转至

基础语法

查询Select

全表查询

Text Only
select * from student;

选择查询

Text Only
select name,age from student

别名

Text Only
select name as 学生姓名, age as 学生年龄 from student

常量和运算

Text Only
select name, score, score*2 as double_score from student

条件查询Where

Text Only
select name,score
from student
where name="鱼皮"

运算符

Text Only
select name, age
from student
where name!="热dog"

空值

is null空值

is not null非空值

Text Only
select name,age,score 
from student
where age is not null

模糊查询 like

like

not like

Text Only
select name,score 
from student
where name not like "%李%"

逻辑运算

Text Only
select
  name,
  score
from
  student
where
  name like "%李%"
  or score > 500

去重distinct

Text Only
select distinct
  class_id,
  exam_num
from
  student

排序

从名为 student 的数据表中选择出学生姓名(name)、年龄(age)和成绩(score),首先按照成绩从大到小排序,如果成绩相同,则按照年龄从小到大排序。

Text Only
select
  name,
  age,
  score
from
  student
order by
  score desc,
  age asc

截断和偏移limit

limit x: 一次获取x条

limit x,y: 从第x-1条开始获取y条

请编写一条 SQL 查询语句,从名为 student 的数据表中选择学生姓名(name)和年龄(age),按照年龄从小到大排序,从第 2 条数据开始、截取 3 个学生的信息。

Text Only
select
  name,
  age
from
  student
order by
  age asc
limit
  1, 3

条件分支

假设有一个学生表 student,包含以下字段:name(姓名)、age(年龄)。请你编写一个 SQL 查询,将学生按照年龄划分为三个年龄等级(age_level):60 岁以上为 "老同学",20 岁以上(不包括 60 岁以上)为 "年轻",20 岁及以下、以及没有年龄信息为 "小同学"。

返回结果应包含学生的姓名(name)和年龄等级(age_level),并按姓名升序排序。

Text Only
CASE WHEN (条件1) THEN 结果1
       WHEN (条件2) THEN 结果2
       ...
       ELSE 其他结果 END
Text Only
select
  name,
  case
    when (age > 60) then "老同学"
    when (age < 20 or age is null) then "小同学"
    else "年轻"
  end as age_level
from
  student
order by
  name asc;

函数

时间函数

常用的时间函数有:

  • DATE:获取当前日期
  • DATETIME:获取当前日期时间
  • TIME:获取当前时间

image-20240127102301800

Text Only
-- 获取当前日期
SELECT DATE() AS current_date;

-- 获取当前日期时间
SELECT DATETIME() AS current_datetime;

-- 获取当前时间
SELECT TIME() AS current_time;

字符串处理

Text Only
UPPER()
LENGTH()
LOWER()
Text Only
select id,name,UPPER(name) as upper_name from student
where name="热dog"

聚合函数

常见的聚合函数包括:

  • COUNT:计算指定列的行数或非空值的数量。
  • SUM:计算指定列的数值之和。
  • AVG:计算指定列的数值平均值。
  • MAX:找出指定列的最大值。
  • MIN:找出指定列的最小值。
Text Only
select
  sum(score) as total_score,
  avg(score) as avg_score,
  max(score) as max_score,
  min(score) as min_score
from
  student

分组聚合

单字段分组

某个学校可以按照班级将学生分组,并对每个班级进行统计。查看每个班级有多少学生、每个班级的平均成绩。这样我们就能够对学校各班的学生情况有一个整体的了解,而不是单纯看个别学生的信息。

在 SQL 中,通常使用 GROUP BY 关键字对数据进行分组

假设有一个学生表 student,包含以下字段:id(学号)、name(姓名)、class_id(班级编号)、score(成绩)。请你编写一个 SQL 查询,统计学生表中的班级编号(class_id)和每个班级的平均成绩(avg_score)

Text Only
select
  class_id,
  avg(score) as avg_score
from
  student
group by
  class_id

多字段分组

多字段分组查询表中 每个客户 购买的 每种商品 的总金额,相当于按照客户编号和商品编号分组:

Text Only
-- 查询每个用户购买的每种商品的总金额,按照客户编号和商品编号分组
SELECT customer_id, product_id, SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id, product_id;

假设有一个学生表 student,包含以下字段:id(学号)、name(姓名)、class_id(班级编号)、exam_num(考试次数)、score(成绩)。请你编写一个 SQL 查询,统计学生表中的班级编号(class_id),考试次数(exam_num)和每个班级每次考试的总学生人数(total_num)。

Text Only
select
  class_id,
  exam_num,
  count(*) as total_num
from
  student
group by
  class_id,
  exam_num

having子句

在 SQL 中,HAVING 子句用于在分组聚合后对分组进行过滤。它允许我们对分组后的结果进行条件筛选,只保留满足特定条件的分组。

HAVING 子句与条件查询 WHERE 子句的区别在于,WHERE 子句用于在 分组之前 进行过滤,而 HAVING 子句用于在 分组之后 进行过滤。

假设有一个学生表 student,包含以下字段:id(学号)、name(姓名)、class_id(班级编号)、score(成绩)。请你编写一个 SQL 查询,统计学生表中班级的总成绩超过 150 分的班级编号(class_id)和总成绩(total_score)。

Text Only
select
  class_id,
  sum(score) as total_score
from
  student
group by
  class_id
having
  sum(score) > 150

关联查询 - cross join

在 SQL 中,关联查询是一种用于联合多个数据表中的数据的查询方式。

其中,CROSS JOIN 是一种简单的关联查询,不需要任何条件来匹配行,它直接将左表的 每一行 与右表的 每一行 进行组合,返回的结果是两个表的笛卡尔积。

假设有一个学生表 student ,包含以下字段:id(学号)、name(姓名)、age(年龄)、class_id(班级编号);还有一个班级表 class ,包含以下字段:id(班级编号)、name(班级名称)。

请你编写一个 SQL 查询,将学生表和班级表的所有行组合在一起,并返回学生姓名(student_name)、学生年龄(student_age)、班级编号(class_id)以及班级名称(class_name)。

Text Only
select s.name as student_name, s.age as student_age,s.class_id,c.name as class_name
from student s
cross join class c

关联查询 - inner join

它根据两个表之间的关联条件,将满足条件的行组合在一起。

注意,INNER JOIN 只返回两个表中满足关联条件的交集部分,即在两个表中都存在的匹配行。

假设有一个学生表 student,包含以下字段:id(学号)、name(姓名)、age(年龄)、class_id(班级编号)。还有一个班级表 class,包含以下字段:id(班级编号)、name(班级名称)、level(班级级别)。

请你编写一个 SQL 查询,根据学生表和班级表之间的班级编号进行匹配,返回学生姓名(student_name)、学生年龄(student_age)、班级编号(class_id)、班级名称(class_name)、班级级别(class_level)。

Text Only
select s.name as student_name,s.age as student_age,s.class_id,c.name as class_name,c.level as class_level
from student s
join class c on c.id=s.class_id

关联查询 - outer join

在 SQL 中,OUTER JOIN 是一种关联查询方式,它根据指定的关联条件,将两个表中满足条件的行组合在一起,并 包含没有匹配的行

在 OUTER JOIN 中,包括 LEFT OUTER JOIN 和 RIGHT OUTER JOIN 两种类型,它们分别表示查询左表和右表的所有行(即使没有被匹配),再加上满足条件的交集部分。

Text Only
select s.name as student_name,s.age as student_age,s.class_id,c.name as class_name,c.level as class_level
from student s
left join class c on c.id=s.class_id

子查询

子查询是指在一个查询语句内部 嵌套 另一个完整的查询语句,内层查询被称为子查询。子查询可以用于获取更复杂的查询结果或者用于过滤数据。

当执行包含子查询的查询语句时,数据库引擎会首先执行子查询,然后将其结果作为条件或数据源来执行外层查询。

打个比方,子查询就像是在一个盒子中的盒子,外层查询是大盒子,内层查询是小盒子。执行查询时,我们首先打开小盒子获取结果,然后将小盒子的结果放到大盒子中继续处理。

假设有一个学生表 student,包含以下字段:id(学号)、name(姓名)、age(年龄)、score(分数)、class_id(班级编号)。还有一个班级表 class,包含以下字段:id(班级编号)、name(班级名称)

请你编写一个 SQL 查询,使用子查询的方式来获取存在对应班级的学生的所有数据,返回学生姓名(name)、分数(score)、班级编号(class_id)字段。

Text Only
select
  s.name,
  s.score,
  s.class_id
from
  student s
where
  s.class_id in (
    select distinct
      id
    from
      class
  )

子查询 - exists

子查询中的一种特殊类型是 "exists" 子查询,用于检查主查询的结果集是否存在满足条件的记录,它返回布尔值(True 或 False),而不返回实际的数据。

和 exists 相对的是 not exists,用于查找不满足存在条件的记录。

题目

假设有一个学生表 student,包含以下字段:id(学号)、name(姓名)、age(年龄)、score(分数)、class_id(班级编号)。还有一个班级表 class,包含以下字段:id(班级编号)、name(班级名称)。

请你编写一个 SQL 查询,使用 exists 子查询的方式来获取 不存在对应班级的 学生的所有数据,返回学生姓名(name)、年龄(age)、班级编号(class_id)字段。

Text Only
select
  s.name,
  s.age,
  s.class_id
from
  student s
where
  not exists (
    select distinct
      id
    from
      class
    where
      class.id = s.class_id
  )

查询进阶 - 组合查询