mysql 专业笔记 -- 第 8 章:使用变量

第 8.1 节:设置变量

  1. 你可以使用 SET 将变量设置为特定的字符串、数字或日期:
sql 复制代码
SET @var_string = 'my_var';
SET @var_num = '2';
SET @var_date = '2015-07-20';
  1. 你可以使用 := 将变量设置为 SELECT 语句的结果:
sql 复制代码
SELECT @var := '123';

(注意:当不使用 SET 语法赋值时,你需要使用 :=,因为其他语句(如 SELECT、UPDATE)中的 = 用于比较,所以当你添加冒号后跟等号时,表示"这不是比较,而是 SET"。)

  1. 你可以使用 INTO 将变量设置为 SELECT 语句的结果(这在需要动态选择要查询的分区时特别有用):
sql 复制代码
SET @start_date = '2015-07-20';
SET @end_date = '2016-01-31';

-- 获取用作分区名的年月值
SET @start_yearmonth = (SELECT EXTRACT(YEAR_MONTH FROM @start_date));
SET @end_yearmonth = (SELECT EXTRACT(YEAR_MONTH FROM @end_date));

-- 将分区放入变量
SELECT GROUP_CONCAT(partition_name)
FROM information_schema.partitions
WHERE table_name = 'partitioned_table'
  AND SUBSTRING_INDEX(partition_name, 'p', -1) BETWEEN @start_yearmonth AND @end_yearmonth
INTO @partitions;

-- 将查询放入变量。你需要这样做,因为 MySQL 在那个位置不能识别变量。你需要将变量的值与查询的其余部分拼接,然后作为预处理语句执行。
SET @query = CONCAT(
    'CREATE TABLE part_of_partitioned_table (PRIMARY KEY(id)) ',
    'SELECT partitioned_table.* ',
    'FROM partitioned_table PARTITION(', @partitions, ') ',
    'JOIN users u USING(user_id) ',
    'WHERE DATE(partitioned_table.date) BETWEEN ', @start_date, ' AND ', @end_date
);

-- 从 @query 准备语句
PREPARE stmt FROM @query;

-- 删除表(如果存在)
DROP TABLE IF EXISTS tech.part_of_partitioned_table;

-- 使用语句执行创建表
EXECUTE stmt;

第 8.2 节:在 SELECT 语句中使用变量实现行号和分组

假设我们有一个 team_person 表,如下所示:

图片占位符

sql 复制代码
CREATE TABLE team_person AS
SELECT 'A' team, 'John' person UNION ALL
SELECT 'B' team, 'Smith' person UNION ALL
SELECT 'A' team, 'Walter' person UNION ALL
SELECT 'A' team, 'Louis' person UNION ALL
SELECT 'C' team, 'Elizabeth' person UNION ALL
SELECT 'B' team, 'Wayne' person;

要为 team_person 表添加行号列,可以使用以下任一方法:

sql 复制代码
SELECT @row_no := @row_no + 1 AS row_number, team, person
FROM team_person, (SELECT @row_no := 0) t;

或者:

sql 复制代码
SET @row_no := 0;
SELECT @row_no := @row_no + 1 AS row_number, team, person
FROM team_person;

以上都会输出以下结果(示例):

复制代码
+------------+------+-----------+
| row_number | team | person    |
+------------+------+-----------+
| 1          | A    | John      |
| 2          | A    | Walter    |
| 3          | A    | Louis     |
| 4          | B    | Smith     |
| 5          | B    | Wayne     |
| 6          | C    | Elizabeth |
+------------+------+-----------+

最后,如果我们想要按 team 列分组生成行号:

sql 复制代码
SELECT
    @row_no := IF(@prev_val = t.team, @row_no + 1, 1) AS row_number,
    @prev_val := t.team AS team,
    t.person
FROM team_person t,
    (SELECT @row_no := 0) x,
    (SELECT @prev_val := '') y
ORDER BY t.team ASC, t.person DESC;

输出结果(示例):

复制代码
+------------+------+-----------+
| row_number | team | person    |
+------------+------+-----------+
| 1          | A    | Walter    |
| 2          | A    | Louis     |
| 3          | A    | John      |
| 1          | B    | Wayne     |
| 2          | B    | Smith     |
| 1          | C    | Elizabeth |
+------------+------+-----------+
相关推荐
聚美智数2 小时前
网安查询-备案查询-网络安全查询API接口介绍
网络·数据库·web安全
XiHongShi20162 小时前
cpuz分享,建议保存
单片机·学习
minglie12 小时前
zynq中axi_dma的sg模式采集--PL搭建
学习
代码方舟2 小时前
O2O二手车交易平台B端车商管理后台:基于天远车信盟出险构建自动化车况评估网关
java·运维·人工智能·自动化
坐吃山猪2 小时前
【多线程】Semaphore使用
java·数据库·oracle·多线程
噜~噜~噜~2 小时前
操作系统笔记-2.3.6 管程
笔记·操作系统
数智启示录2 小时前
PostgreSQL 内存调优实战(第 12 篇):work_mem 只调大 64 倍,峰值为什么远不止 64 倍
运维·数据库·经验分享·postgresql·面试
传奇开心果编程2 小时前
【Rust入门知识点学与练】第3课:String 与 &str 的区别
开发语言·学习·rust
云登指纹浏览器3 小时前
RPA 与指纹浏览器集成:多账号自动化运营的5项环境配置
运维·自动化·rpa