Post

MySQL Select Base

MySQL Select Base

  • 基本的 SQL 语法:了解 SQL 的基本语法结构,包括 SELECT、FROM、WHERE、GROUP BY、ORDER BY 等关键字的使用方法
  • 表的创建和管理:理解如何创建表,定义列的数据类型,以及如何管理表的结构,包括添加、删除、修改列等操作
  • 索引:了解索引的概念以及如何在表上创建索引,以提高查询性能
  • 聚合函数:掌握聚合函数如 COUNT、SUM、AVG、MIN、MAX 等的使用,以便对数据进行统计和计算
  • GROUP BY 子句:学习如何使用 GROUP BY 子句对数据进行分组,并结合聚合函数进行分组统计
  • HAVING 子句:了解 HAVING 子句的作用,它与 WHERE 子句的区别,以及在 GROUP BY 后进行条件过滤的用法
  • 连接(JOIN):学习不同类型的连接操作,如 INNER JOIN、LEFT JOIN、RIGHT JOIN 等,以及它们在查询中的应用
  • 子查询:掌握如何在 SELECT 语句中嵌套使用子查询来实现复杂的查询逻辑
  • 函数:熟悉 MySQL 提供的各种函数,包括数学函数、日期函数、字符串函数等,以及它们在查询中的应用
  • 模糊查询:了解如何使用 LIKE 关键字进行模糊匹配,以及通配符的使用方法,如 %_
  • 排序和分页:掌握 ORDER BY 子句的使用,以对查询结果进行排序,并了解 LIMIT 子句的用法,以实现分页查询
  • 数据类型转换和格式化:了解如何对查询结果进行数据类型转换和格式化,以满足特定的输出需求

基本 SQL 语法

  • SELECT:指定要检索的列或表达式
  • FROM:指定要从中检索数据的表或视图
  • WHERE:指定条件,以过滤检索的行
  • GROUP BY:按照指定的列对检索的数据进行分组
  • HAVING:对分组后的结果进行条件过滤
  • ORDER BY:指定结果的排序顺序
  • LIMIT(在一些数据库系统中):限制返回的行数
  • 例子

    假设我们有一个名为 orders的表,其中包含了订单信息,包括订单号、客户 ID、订单日期和订单金额等字段。我们想要检索每个客户的订单总金额,并按照订单总金额降序排列,只显示订单总金额大于 1000 的客户,最多显示前 10 个客户的结果。下面是相应的 SQL 查询:

    1
    2
    3
    4
    5
    6
    
    SELECT customer_id, SUM(order_amount) AS total_amount
    FROM orders
    GROUP BY customer_id
    HAVING total_amount > 1000
    ORDER BY total_amount DESC
    LIMIT 10;
    
    • 解释

      • SELECT customer_id, SUM(order_amount) AS total_amount:我们选择了客户 ID 和订单金额的总和,并使用 AS 关键字给总金额取了一个别名 total_amount
      • FROM orders:我们从 orders 表中检索数据
      • GROUP BY customer_id:我们按照客户 ID 进行分组,以计算每个客户的订单总金额
      • HAVING total_amount > 1000:我们使用 HAVING 子句来过滤总金额大于 1000 的客户
      • ORDER BY total_amount DESC:我们按照订单总金额的降序排列结果
      • LIMIT 10:最后,我们使用 LIMIT 子句限制结果集的大小为 10,只显示前 10 个客户的结果

运算符

运算符 名称 示例
+ 加法 SELECT 5 + 3; 结果为 8
- 减法 SELECT 10 - 4; 结果为 6
* 乘法 SELECT 7 * 6; 结果为 42
/ 除法 SELECT 15 / 3; 结果为 5
% 取模 SELECT 17 % 5; 结果为 2
= 等于 SELECT * FROM users WHERE age = 25;
<> 不等于 SELECT * FROM users WHERE age <> 25;
> 大于 SELECT * FROM users WHERE age > 25;
< 小于 SELECT * FROM users WHERE age < 25;
>= 大于等于 SELECT * FROM users WHERE age >= 25;
<= 小于等于 SELECT * FROM users WHERE age <= 25;
AND 逻辑与 SELECT * FROM users WHERE age > 25 AND gender = 'M';
OR 逻辑或 SELECT * FROM users WHERE age > 25 OR gender = 'F';
NOT 逻辑非 SELECT * FROM users WHERE NOT age > 25;
BETWEEN 在某个范围内 SELECT * FROM users WHERE age BETWEEN 20 AND 30;
IN 在某个集合内 SELECT * FROM users WHERE age IN (25, 30, 35);
LIKE 模糊匹配 SELECT * FROM users WHERE name LIKE 'J%';
IS NULL 是否为 NULL SELECT * FROM users WHERE email IS NULL;
IS NOT NULL 是否不为 NULL SELECT * FROM users WHERE email IS NOT NULL;
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
SELECT
    users.id,
    users.name,
    users.age,
    users.gender,
    users.email,
    (users.age + 5) AS future_age,
    (users.age - 3) AS past_age,
    (users.age * 2) AS double_age,
    ROUND(users.age / 3, 2) AS third_age,
    (users.age % 2) AS odd_or_even,
    CASE
        WHEN users.age = 25 THEN 'Twenty-five'
        WHEN users.age > 25 THEN 'Older than twenty-five'
        ELSE 'Younger than twenty-five'
    END AS age_category,
    CASE
        WHEN users.gender = 'M' THEN 'Male'
        WHEN users.gender = 'F' THEN 'Female'
        ELSE 'Unknown'
    END AS gender_text,
    CONCAT(users.name, ' (', users.gender, ')') AS name_and_gender
FROM
    users
WHERE
    users.age BETWEEN 20 AND 30
    AND users.gender IN ('M', 'F')
    AND users.email IS NOT NULL
    AND (users.name LIKE 'J%' OR users.name LIKE 'S%')
ORDER BY
    users.age DESC
LIMIT 10;
  • 解释

    1. 算术运算符: +-*/%
    2. 比较运算符: =<>><>=<=
    3. 逻辑运算符: ANDORNOT
    4. 范围运算符: BETWEEN
    5. 集合运算符: IN
    6. 模糊匹配运算符: LIKE
    7. NULL 检测运算符: IS NULLIS NOT NULL
    8. 字符串连接运算符: CONCAT()
    9. 数学函数: ROUND()
    10. 条件表达式: CASE ... WHEN ... THEN ... ELSE ... END

这个查询从 users 表中选择特定的列,对它们进行各种运算,并根据条件进行过滤和排序,最后返回前 10 条结果。

聚合函数

聚合函数 描述 示例
COUNT(DISTINCT column_name) 统计指定列中不同值的个数 SELECT COUNT(DISTINCT customer_id) FROM orders;
SUM(DISTINCT column_name) 计算指定列中不同值的总和 SELECT SUM(DISTINCT order_amount) FROM orders;
AVG(DISTINCT column_name) 计算指定列中不同值的平均值 SELECT AVG(DISTINCT salary) FROM employees;
VAR_POP(column_name) 计算总体方差 SELECT VAR_POP(sales_amount) FROM orders;
VAR_SAMP(column_name) 计算样本方差 SELECT VAR_SAMP(sales_amount) FROM orders;
STDEV_POP(column_name) 计算总体标准差 SELECT STDEV_POP(sales_amount) FROM orders;
STDEV_SAMP(column_name) 计算样本标准差 SELECT STDEV_SAMP(sales_amount) FROM orders;
BIT_AND(column_name) 计算指定列中所有值的按位与 SELECT BIT_AND(status) FROM orders;
BIT_OR(column_name) 计算指定列中所有值的按位或 SELECT BIT_OR(status) FROM orders;
BIT_XOR(column_name) 计算指定列中所有值的按位异或 SELECT BIT_XOR(status) FROM orders;
  • 例子

    假设我们有一个名为 sales 的表,其中包含以下字段

    • id: 销售订单 ID
    • product: 产品名称
    • amount: 销售金额
    • status: 销售状态(1 表示已完成, 0 表示未完成)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      SELECT
          product,
          COUNT(*) AS total_orders,
          SUM(amount) AS total_sales,
          AVG(amount) AS avg_sale_amount,
          VAR_POP(amount) AS population_variance,
          VAR_SAMP(amount) AS sample_variance,
          STDEV_POP(amount) AS population_std_dev,
          STDEV_SAMP(amount) AS sample_std_dev,
          BIT_AND(status) AS all_completed,
          BIT_OR(status) AS any_completed,
          BIT_XOR(status) AS mix_of_completed_and_not
      FROM
          sales
      GROUP BY
          product;
      
    • 解释

      • product: 产品名称
      • total_orders: 每个产品的总订单数
      • total_sales: 每个产品的总销售额
      • avg_sale_amount: 每个产品的平均销售额
      • population_variance: 每个产品销售额的总体方差
      • sample_variance: 每个产品销售额的样本方差
      • population_std_dev: 每个产品销售额的总体标准差
      • sample_std_dev: 每个产品销售额的样本标准差
      • all_completed: 每个产品是否所有订单都已完成(1 表示是, 0 表示否)
      • any_completed: 每个产品是否有任何订单已完成(1 表示是, 0 表示否)
      • mix_of_completed_and_not: 每个产品是否存在既有已完成又有未完成的订单(1 表示是, 0 表示否)

Group By & Group By 子句

用途 示例
根据一个或多个列对结果集进行分组 SELECT department, COUNT(*) AS num_employees FROM employees GROUP BY department;
与聚合函数结合使用,对分组数据进行统计 SELECT product, SUM(sales_amount) AS total_sales FROM sales GROUP BY product;
对分组结果进行筛选 SELECT category, MAX(sales_amount) AS max_sales FROM sales GROUP BY category HAVING max_sales > 1000;
对分组结果进行排序 SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department ORDER BY avg_salary DESC;
嵌套多个 GROUP BY 子句进行多层分组 SELECT country, city, COUNT(*) AS num_customers FROM customers GROUP BY country, city;
ROLLUPCUBE 一起使用进行分组结果汇总 SELECT category, product, SUM(sales_amount) AS total_sales FROM sales GROUP BY ROLLUP(category, product);
  • 例子

    假设我们有一个名为 sales 的数据表,其包含以下字段:

    • id: 销售订单 ID
    • product: 产品名称
    • category: 产品类别
    • customer: 客户名称
    • amount: 销售金额
    • date: 销售日期
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    SELECT
        category,
        product,
        customer,
        DATE_FORMAT(date, '%Y-%m') AS sales_month,
        COUNT(*) AS total_orders,
        SUM(amount) AS total_sales,
        AVG(amount) AS avg_sale_amount
    FROM
        sales
    GROUP BY
        category, product, customer, DATE_FORMAT(date, '%Y-%m')
    ORDER BY
        total_sales DESC
    LIMIT 10;
    
    • 解释

      • category: 产品类别
      • product: 产品名称
      • customer: 客户名称
      • sales_month: 销售月份
      • total_orders: 每个产品-客户-月份组合的总订单数
      • total_sales: 每个产品-客户-月份组合的总销售额
      • avg_sale_amount: 每个产品-客户-月份组合的平均销售额

    查询结果会按照总销售额降序排列,取前 10 条记录

HAVING 子句

HAVING 子句是用来对 GROUP BY 子句产生的分组结果进行筛选的,它通常与聚合函数一起使用。它的作用是在聚合操作之后对数据进行过滤。

  • 例子
1
2
3
4
5
6
7
8
9
SELECT
    department,
    COUNT(*) AS num_employees
FROM
    employees
GROUP BY
    department
HAVING
    num_employees > 10;
  • 解释
  1. GROUP BY department 将数据按照部门进行分组。
  2. COUNT(*) 统计每个部门的员工数量。
  3. HAVING num_employees > 10 对分组结果进行筛选,只保留员工数量大于 10 人的部门。
  • HAVING 子句的常见用法包括:

    • 对分组结果进行过滤,保留满足条件的分组
    • 配合聚合函数使用,对分组数据进行过滤
    • WHERE 子句配合使用,先对原始数据进行过滤,再对分组结果进行过滤
  • 使用 HAVING 子句时需要注意以下几点:

    1. HAVING 子句必须在 GROUP BY 子句之后使用。
    2. HAVING 子句中可以使用聚合函数,但 WHERE 子句中不能使用聚合函数。
    3. HAVING 子句的条件表达式可以引用 GROUP BY 子句中的字段。

Join

Join 类型 定义 优点 缺点
Inner Join 只返回两个表中都存在的记录 简单高效,可以快速找到匹配数据 会丢失未匹配的记录
Left Join 返回左表的所有记录,即使右表中没有匹配的记录 可以保留左表的所有记录 可能会返回大量 NULL 值
Right Join 返回右表的所有记录,即使左表中没有匹配的记录 可以保留右表的所有记录 可能会返回大量 NULL 值
Outer Join 返回左表和右表中所有的记录,即使两表中没有匹配的记录 可以保留两个表中的所有记录 可能会返回大量 NULL 值
Cross Join 返回左表和右表中所有记录的笛卡尔积 可以快速生成大量数据用于测试 当表的数据量很大时,结果集会非常庞大,可能会导致性能问题
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
-- Inner Join
SELECT u.name, o.order_date, o.total_amount
FROM users u
INNER JOIN orders o
ON u.id = o.user_id;

-- Left Join
SELECT u.name, o.order_date, o.total_amount
FROM users u
LEFT JOIN orders o
ON u.id = o.user_id;

-- Right Join
SELECT u.name, o.order_date, o.total_amount
FROM users u
RIGHT JOIN orders o
ON u.id = o.user_id;

-- Outer Join
SELECT u.name, o.order_date, o.total_amount
FROM users u
FULL OUTER JOIN orders o
ON u.id = o.user_id;

-- Cross Join
SELECT u.name, o.order_date, o.total_amount
FROM users u
CROSS JOIN orders o;

子查询

  • 子查询的基本用法

    子查询是指在一个 SQL 语句中嵌入另一个 SQL 语句。子查询可以出现在 SELECT、FROM、WHERE 或 HAVING 子句中。

  • 一些常见的子查询用法如下:

    1. 单行子查询: 返回单个值,可以在 WHERE 子句中使用比较运算符比如 =<>等。
    2. 多行子查询: 返回多个值,可以在 WHERE 子句中使用 INNOT INEXISTSNOT EXISTS 等。
    3. 相关子查询: 子查询引用了外部查询的列,子查询的执行依赖于外部查询。
    4. 标量子查询: 子查询返回单个值,可以在 SELECT 语句的选择列表中使用。
    5. 表子查询: 子查询返回一个虚拟表,可以在 FROM 子句中使用。
  • 使用子查询时需要注意的事项

    1. 子查询的执行顺序: 在 SQL 语句执行时,子查询先于外部查询执行。
    2. 子查询返回值的类型和数量: 单行子查询返回单个值,多行子查询返回多个值。需要确保子查询返回的数据类型和数量与外部查询的要求相匹配。
    3. 性能问题: 复杂的子查询可能会影响查询性能,可以考虑使用连接或临时表等替代方案。
    4. 子查询嵌套层数: 过多的嵌套子查询可能会降低查询效率,建议控制在 3-4 层以内。
    5. 避免无限循环: 当子查询引用了外部查询的列时,需要小心避免无限循环。
  • 例子

1
2
3
4
5
6
7
8
9
10
11
12
13
-- 查找所有销售额高于平均销售额的订单
SELECT
    order_id,
    total_amount
FROM
    orders
WHERE
    total_amount > (
        SELECT
            AVG(total_amount)
        FROM
            orders
    );

函数

日期函数

函数名称 功能 示例
CURRENT_DATE() 返回当前日期 SELECT CURRENT_DATE();
CURRENT_TIME() 返回当前时间 SELECT CURRENT_TIME();
CURRENT_TIMESTAMP() 返回当前日期和时间 SELECT CURRENT_TIMESTAMP();
DATE(expr) 从日期或日期时间表达式中提取日期部分 SELECT DATE(‘2023-05-23 10:30:45’);
TIME(expr) 从日期或日期时间表达式中提取时间部分 SELECT TIME(‘2023-05-23 10:30:45’);
YEAR(date) 返回日期中的年份 SELECT YEAR(‘2023-05-23’);
MONTH(date) 返回日期中的月份 SELECT MONTH(‘2023-05-23’);
DAY(date) 返回日期中的天数 SELECT DAY(‘2023-05-23’);
HOUR(time) 返回时间中的小时数 SELECT HOUR(‘10:30:45’);
MINUTE(time) 返回时间中的分钟数 SELECT MINUTE(‘10:30:45’);
SECOND(time) 返回时间中的秒数 SELECT SECOND(‘10:30:45’);
DATEDIFF(date1, date2) 返回两个日期之间的天数差 SELECT DATEDIFF(‘2023-05-23’, ‘2023-05-01’);
TIMEDIFF(time1, time2) 返回两个时间之间的差 SELECT TIMEDIFF(‘10:30:45’, ‘08:20:15’);
DATE_FORMAT(date, format) 将日期格式化为指定格式 SELECT DATE_FORMAT(‘2023-05-23’, ‘%Y-%m-%d’);

字符串

函数名称 功能 示例
CONCAT(str1, str2, …) 连接多个字符串 SELECT CONCAT(‘Hello’, ‘, ‘, ‘World!’);
SUBSTRING(str, pos, len) 从字符串中提取子字符串 SELECT SUBSTRING(‘Hello World’, 7, 5);
LENGTH(str) 返回字符串长度 SELECT LENGTH(‘Hello World’);
LOWER(str) 将字符串转换为小写 SELECT LOWER(‘Hello World’);
UPPER(str) 将字符串转换为大写 SELECT UPPER(‘Hello World’);
TRIM(str) 去除字符串两端的空白字符 SELECT TRIM(‘ Hello World ‘);
REPLACE(str, from_str, to_str) 替换字符串中的子字符串 SELECT REPLACE(‘Hello World’, ‘World’, ‘MySQL’);
STRCMP(str1, str2) 比较两个字符串的大小 SELECT STRCMP(‘Apple’, ‘Banana’);
INSTR(str, substr) 返回子字符串在字符串中首次出现的位置 SELECT INSTR(‘Hello World’, ‘World’);
REVERSE(str) 反转字符串 SELECT REVERSE(‘Hello World’);
LPAD(str, len, padstr) 在左侧用指定字符串填充字符串至指定长度 SELECT LPAD(‘Hello’, 10, ‘0’);
RPAD(str, len, padstr) 在右侧用指定字符串填充字符串至指定长度 SELECT RPAD(‘Hello’, 10, ‘0’);

数字相关

函数名称 功能 示例
ABS(x) 返回数字的绝对值 SELECT ABS(-10);
CEILING(x) 返回大于或等于指定数字的最小整数 SELECT CEILING(3.14);
FLOOR(x) 返回小于或等于指定数字的最大整数 SELECT FLOOR(3.14);
ROUND(x, d) 将数字四舍五入为指定小数位数 SELECT ROUND(3.14159, 2);
TRUNCATE(x, d) 将数字截断为指定小数位数 SELECT TRUNCATE(3.14159, 2);
MOD(x, y) 返回 x 除以 y 的余数 SELECT MOD(10, 3);
POWER(x, y) 返回 x 的 y 次方 SELECT POWER(2, 3);
SQRT(x) 返回数字的平方根 SELECT SQRT(16);
EXP(x) 返回 e 的 x 次方 SELECT EXP(2);
LOG(x) 返回数字的自然对数 SELECT LOG(10);
LOG10(x) 返回数字的常用对数 SELECT LOG10(100);
RAND() 返回 0 到 1 之间的随机数 SELECT RAND();

模糊查询

查询方式 描述 示例
LIKE 使用通配符 %_ 进行模糊匹配 SELECT * FROM users WHERE name LIKE 'John%'<br>查找所有名字以”John”开头的用户
REGEXP 使用正则表达式进行模糊匹配 SELECT * FROM users WHERE name REGEXP '^John'<br>查找所有名字以”John”开头的用户
FULLTEXT 对文本类型字段进行全文搜索 SELECT * FROM articles WHERE MATCH(title, content) AGAINST('MySQL')<br>查找标题或内容包含”MySQL”的文章
CONCAT() 将多个字段拼接后进行模糊查询 SELECT * FROM users WHERE CONCAT(first_name, ' ', last_name) LIKE '%John%'<br>查找姓名中包含”John”的用户
INSTR() 判断字符串是否包含指定子串 SELECT * FROM products WHERE INSTR(name, 'iPhone') > 0<br>查找名称中包含”iPhone”的产品
SUBSTRING() 提取字符串的子串进行匹配 SELECT * FROM users WHERE SUBSTRING(email, 1, 5) = 'john@'<br>查找邮箱前缀为”john@”的用户
  • 例子
  • 假设我们有一个名为 products 的表,其中包含以下字段:

    • id: 产品 ID
    • name: 产品名称
    • description: 产品描述
    • category: 产品分类
    • 现在我们需要查找所有名称包含”iPhone”、分类为”手机”、并且描述中包含”5G”的产品。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      SELECT
          id,
          name,
          description,
          category
      FROM
          products
      WHERE
          name LIKE '%iPhone%'
          AND category = '手机'
          AND description LIKE '%5G%'
      
    • 解释

      1. name LIKE '%iPhone%': 使用 LIKE 操作符进行模糊匹配,查找名称中包含”iPhone”的产品。
      2. category = '手机': 精确匹配分类为”手机”的产品。
      3. description LIKE '%5G%': 使用 LIKE 操作符查找描述中包含”5G”的产品。

排序和分页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT
    id,
    name,
    description,
    category
FROM
    products
WHERE
    name LIKE '%iPhone%'
    AND category = '手机'
    AND description LIKE '%5G%'
ORDER BY
    id DESC
LIMIT
    10 OFFSET 20
  • 解释

    1. WHERE 子句: 与前面的示例相同,用于进行模糊查询
    2. ORDER BY id DESC: 按照产品 ID 倒序排列结果集
    3. LIMIT 10 OFFSET 20: 实现分页功能,取第 21-30 条记录(第 3 页,每页 10 条)

这样我们就可以在满足业务查询条件的基础上,对结果集进行排序和分页展示。这在实际开发中非常有用,可以让用户体验更加流畅

  • 排序可以使用 ORDER BY 子句,支持多个字段,并可以指定升序(ASC)或降序(DESC)
  • 分页可以使用 LIMITOFFSET 子句组合实现,LIMIT 指定每页显示的记录数,OFFSET 指定跳过的记录数

分页计算公式

  • 计算
    • 总记录数:totalRecord
    • 每页最大记录数:maxResult
    • totalPage = (totalRecord + maxResult -1) / maxResult;
    • 其中 maxResult - 1 就是 totalRecord / maxResult 的最大的余数
  • 动态
    • select * from table limit (page-1)*20,20;
    • 当页面传递过来 page 为 1 时查询 0~20,当 page 为 2 时查询 20~40 以此类推,求正确公式公式。
    • select * from table order by id asc limit (page-1)*20,20;

条件 & 循环

条件语句

  • IF 语句:

    1
    2
    3
    4
    5
    6
    7
    
    IF condition THEN
        statement_list
    [ELSEIF condition THEN
        statement_list]
    [ELSE
        statement_list]
    END IF;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    DELIMITER //
    CREATE PROCEDURE check_age(IN user_age INT)
    BEGIN
        IF user_age < 18 THEN
            SELECT 'Minor';
        ELSEIF user_age >= 18 AND user_age < 65 THEN
            SELECT 'Adult';
        ELSE
            SELECT 'Senior';
        END IF;
    END //
    DELIMITER ;
    
  • CASE 语句

    1
    2
    3
    4
    5
    
    CASE case_expression
        WHEN when_expression THEN statement_list
        [WHEN when_expression THEN statement_list] ...
        [ELSE statement_list]
    END CASE;
    
    1
    2
    3
    4
    5
    6
    7
    8
    
    SELECT
       name,
       CASE gender
           WHEN 'M' THEN 'Male'
           WHEN 'F' THEN 'Female'
           ELSE 'Unknown'
       END AS gender_text
    FROM users;
    

循环语句

  • WHILE 循环:

    1
    2
    3
    
    [begin_label:] WHILE search_condition DO
        statement_list
    END WHILE [end_label];
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    DELIMITER //
    CREATE PROCEDURE print_numbers(IN max_num INT)
    BEGIN
        DECLARE i INT DEFAULT 1;
        WHILE i <= max_num DO
            SELECT i;
            SET i = i + 1;
        END WHILE;
    END //
    DELIMITER ;
    
  • REPEAT 循环:

    1
    2
    3
    4
    
    [begin_label:] REPEAT
        statement_list
    UNTIL search_condition
    END REPEAT [end_label];
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    DELIMITER //
    CREATE PROCEDURE print_even_numbers(IN max_num INT)
    BEGIN
        DECLARE i INT DEFAULT 2;
        REPEAT
            SELECT i;
            SET i = i + 2;
        UNTIL i > max_num
        END REPEAT;
    END //
    DELIMITER ;
    
  • LOOP 循环

    1
    2
    3
    4
    
    [begin_label:] LOOP
        statement_list
        [LEAVE label]
    END LOOP [end_label];
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    DELIMITER //
    CREATE PROCEDURE print_numbers_with_break(IN max_num INT)
    BEGIN
        DECLARE i INT DEFAULT 1;
        numbers_loop: LOOP
            IF i > max_num THEN
                LEAVE numbers_loop;
            END IF;
            SELECT i;
            SET i = i + 1;
        END LOOP numbers_loop;
    END //
    DELIMITER ;
    
This post is licensed under CC BY 4.0 by the author.