下面是sql查询隔行数据的代码,讲一讲怎么实现的啊
SELECT 编号,ISBN,BookName,Writer FROM ( SELECT ROW_NUMBER() OVER(ORDER BY ISBN) 编号,ISBN,BookName,Writer FROM bookinfo_zerobasis) a WHERE a.编号%2=1;
SQL 隔行数据查询代码详解
这段代码的作用是从图书信息表中查询所有奇数行数据(第1、3、5...行)。让我详细讲解其实现原理。
一、代码整体结构
sql
SELECT 编号, ISBN, BookName, Writer FROM ( SELECT ROW_NUMBER() OVER(ORDER BY ISBN) 编号, ISBN, BookName, Writer FROM bookinfo_zerobasis) a WHERE a.编号 % 2 = 1;
这是一个子查询嵌套的结构,分两层实现:
| 层级 | 作用 |
|---|---|
| 内层子查询 | 给每一行分配一个行号(编号) |
| 外层查询 | 筛选出奇数行(编号 % 2 = 1) |
二、内层子查询:生成行号
sql
SELECT ROW_NUMBER() OVER(ORDER BY ISBN) 编号, ISBN, BookName, WriterFROM bookinfo_zerobasis
ROW_NUMBER() 是什么?
| 部分 | 含义 |
|---|---|
ROW_NUMBER() | 窗口函数,为结果集中的每一行分配一个唯一的顺序号 |
OVER(ORDER BY ISBN) | 指定按 ISBN 列排序,然后从1开始编号 |
执行效果
假设 bookinfo_zerobasis 表原始数据(按 ISBN 排序后):
ISBN | BookName | Writer | ROW_NUMBER() 编号 |
978-7-111-12345-6 | 数据库原理 | 王老师 | 1 |
978-7-111-54321-0 | 计算机网络 | 李老师 | 2 |
978-7-302-56789-0 | 操作系统 | 张老师 | 3 |
978-7-302-98765-4 | 数据结构 | 赵老师 | 4 |
978-7-121-11111-1 | Python编程 | 孙老师 | 5 |
内层查询结果(派生表 a):
编号 | ISBN | BookName | Writer |
1 | 978-7-111-12345-6 | 数据库原理 | 王老师 |
2 | 978-7-111-54321-0 | 计算机网络 | 李老师 |
3 | 978-7-302-56789-0 | 操作系统 | 张老师 |
4 | 978-7-302-98765-4 | 数据结构 | 赵老师 |
5 | 978-7-121-11111-1 | Python编程 | 孙老师 |
三、外层查询:筛选奇数行
sql
SELECT 编号, ISBN, BookName, Writer FROM (...) a WHERE a.编号 % 2 = 1;
% 运算符是什么?
符号 | 名称 | 含义 | 示例 |
% | 取模运算符 | 求两数相除的余数 | 5 % 2 = 1(余1) |
编号 % 2 = 1 的含义
编号 | 编号 % 2 | 是否等于 1 | 结果 |
1 | 1 % 2 = 1 | ✅ 是 | 选中(奇数行) |
2 | 2 % 2 = 0 | ❌ 否 | 不选中(偶数行) |
3 | 3 % 2 = 1 | ✅ 是 | 选中(奇数行) |
4 | 4 % 2 = 0 | ❌ 否 | 不选中(偶数行) |
5 | 5 % 2 = 1 | ✅ 是 | 选中(奇数行) |
四、最终结果
编号 | ISBN | BookName | Writer |
1 | 978-7-111-12345-6 | 数据库原理 | 王老师 |
3 | 978-7-302-56789-0 | 操作系统 | 张老师 |
5 | 978-7-121-11111-1 | Python编程 | 孙老师 |
结果:只显示第 1、3、5 行(奇数行)。
五、完整执行流程图
text
┌─────────────────────────────────────────────────────────────┐ │ 步骤1:从 bookinfo_zerobasis 表读取数据 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ISBN │ BookName │ Writer │ │ │ │ │ 978-7-111-12345-6 │ 数据库原理 │ 王老师 │ │ │ │ │ 978-7-111-54321-0 │ 计算机网络 │ 李老师 │ │ │ │ │ 978-7-302-56789-0 │ 操作系统 │ 张老师 │ │ │ │ │ 978-7-302-98765-4 │ 数据结构 │ 赵老师 │ │ │ │ │ 978-7-121-11111-1 │ Python编程 │ 孙老师 │ │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 步骤2:ROW_NUMBER() OVER(ORDER BY ISBN) 分配行号 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 编号 │ ISBN │ BookName │ Writer │ │ │ │ │ 1 │ 978-7-111-12345-6 │ 数据库原理 │ 王老师 │ │ │ │ │ 2 │ 978-7-111-54321-0 │ 计算机网络 │ 李老师 │ │ │ │ │ 3 │ 978-7-302-56789-0 │ 操作系统 │ 张老师 │ │ │ │ │ 4 │ 978-7-302-98765-4 │ 数据结构 │ 赵老师 │ │ │ │ │ 5 │ 978-7-121-11111-1 │ Python编程 │ 孙老师 │ │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 步骤3:WHERE 编号 % 2 = 1 筛选奇数行 │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 编号=1 → 1%2=1 → 选中 │ │ │ │ 编号=2 → 2%2=0 → 跳过 │ │ │ │ 编号=3 → 3%2=1 → 选中 │ │ │ │ 编号=4 → 4%2=0 → 跳过 │ │ │ │ 编号=5 → 5%2=1 → 选中 │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 最终结果:只显示奇数行(第1、3、5行) │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 编号 │ ISBN │ BookName │ Writer │ │ │ │ │ 1 │ 978-7-111-12345-6 │ 数据库原理 │ 王老师 │ │ │ │ │ 3 │ 978-7-302-56789-0 │ 操作系统 │ 张老师 │ │ │ │ │ 5 │ 978-7-121-11111-1 │ Python编程 │ 孙老师 │ │ │ │ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘
六、如何查询偶数行?
sql
-- 查询偶数行(第2、4、6...行)SELECT 编号, ISBN, BookName, Writer FROM ( SELECT ROW_NUMBER() OVER(ORDER BY ISBN) 编号, ISBN, BookName, Writer FROM bookinfo_zerobasis) a WHERE a.编号 % 2 = 0; -- 余数为0的是偶数
七、词源角度:% 取模运算符
| 符号 | 词源 | 含义 |
|---|---|---|
% | 拉丁语 per centum(每百)→ 百分号 | 在编程中被复用为取模运算符 |
取模(Modulo)词源:拉丁语 modulus(小度量、尺度),指测量余数。
八、总结
| 问题 | 答案 |
|---|---|
| 这段代码做什么? | 查询图书信息表中的奇数行数据 |
| 如何实现? | 1. ROW_NUMBER() 给每行分配编号2. WHERE 编号 % 2 = 1 筛选奇数 |
% 是什么? | 取模运算符,求两数相除的余数 |
ROW_NUMBER() 是什么? | 窗口函数,为结果集的行分配顺序号 |
| 如何查偶数行? | 把 =1 改为 =0 |
一句话总结:这段代码先通过 ROW_NUMBER() OVER(ORDER BY ISBN) 为每一行数据按 ISBN 排序后分配一个行号(编号),然后在外层用 WHERE 编号 % 2 = 1 筛选出奇数行——% 是取模运算符,编号 % 2 = 1 表示编号除以 2 余数为 1,即奇数行。这样就实现了隔行查询(只取奇数行)的效果