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 |
+------------+------+-----------+
相关推荐
ly_Enhs20 分钟前
从无光照到 PBR:我的环境光照学习记录
学习·vulkan图形渲染c/c++
小李不想当小白21 分钟前
USART串口数据包(STM32标准库学习笔记)
经验分享·笔记·stm32·单片机·嵌入式硬件·学习
data analyse 45627 分钟前
页面卸载时埋点上报总丢失?sendBeacon 上报与补偿方案
大数据·运维·服务器·前端·数据库·人工智能·数据分析
企查查数据服务28 分钟前
充电桩集采准入:用企业数据做供应商失信批量核验
大数据·数据库·人工智能
xier_ran30 分钟前
【infra之路】AI 编译器学习笔记(八):向量化——把小块变成 SIMD 指令
人工智能·笔记·学习
kmomo..31 分钟前
Linux 驱动开发学习笔记:I2C 子系统从入门到实践
linux·驱动开发·学习
敲上瘾36 分钟前
分布式系统——Redis哨兵:自动故障转移与选举原理
linux·数据库·redis·分布式·缓存·微服务
IT_陈寒42 分钟前
一文搞懂Vite的核心概念
前端·人工智能·后端
一个简单的TTS开发者43 分钟前
中文TTS工具有哪些-8款主流方案横向对比
人工智能·后端·python·indextts
倔强的石头1061 小时前
【Linux指南】进程通信系列(二):匿名管道 —— pipe 的本质、fork 继承与四种读写规则
java·linux·运维